msgpack 1.7.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.
@@ -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_eFrozenError, "can't modify frozen MessagePack::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
  {
@@ -100,14 +95,13 @@ struct msgpack_call_proc_args_t;
100
95
  typedef struct msgpack_call_proc_args_t msgpack_call_proc_args_t;
101
96
  struct msgpack_call_proc_args_t {
102
97
  VALUE proc;
103
- VALUE arg;
104
- VALUE packer;
98
+ VALUE args[2];
105
99
  };
106
100
 
107
101
  VALUE msgpack_packer_try_calling_proc(VALUE value)
108
102
  {
109
103
  msgpack_call_proc_args_t *args = (msgpack_call_proc_args_t *)value;
110
- 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);
111
105
  }
112
106
 
113
107
  bool msgpack_packer_try_write_with_ext_type_lookup(msgpack_packer_t* pk, VALUE v)
@@ -121,11 +115,13 @@ bool msgpack_packer_try_write_with_ext_type_lookup(msgpack_packer_t* pk, VALUE v
121
115
  }
122
116
 
123
117
  if(ext_flags & MSGPACK_EXT_RECURSIVE) {
118
+ VALUE held_buffer = MessagePack_Buffer_hold(&pk->buffer);
119
+
124
120
  msgpack_buffer_t parent_buffer = pk->buffer;
125
121
  msgpack_buffer_init(PACKER_BUFFER_(pk));
126
122
 
127
123
  int exception_occured = 0;
128
- 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 } };
129
125
  rb_protect(msgpack_packer_try_calling_proc, (VALUE)&args, &exception_occured);
130
126
 
131
127
  if (exception_occured) {
@@ -139,8 +135,10 @@ bool msgpack_packer_try_write_with_ext_type_lookup(msgpack_packer_t* pk, VALUE v
139
135
  pk->buffer = parent_buffer;
140
136
  msgpack_packer_write_ext(pk, ext_type, payload);
141
137
  }
138
+
139
+ RB_GC_GUARD(held_buffer);
142
140
  } else {
143
- VALUE payload = rb_funcall(proc, s_call, 1, v);
141
+ VALUE payload = rb_proc_call_with_block(proc, 1, &v, Qnil);
144
142
  StringValue(payload);
145
143
  msgpack_packer_write_ext(pk, ext_type, payload);
146
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);
@@ -106,8 +106,8 @@ VALUE MessagePack_Packer_initialize(int argc, VALUE* argv, VALUE self)
106
106
 
107
107
  msgpack_packer_t *pk = MessagePack_Packer_get(self);
108
108
 
109
- msgpack_packer_ext_registry_init(&pk->ext_registry);
110
- pk->buffer_ref = Qnil;
109
+ msgpack_packer_ext_registry_init(self, &pk->ext_registry);
110
+ pk->buffer_ref = MessagePack_Buffer_wrap(PACKER_BUFFER_(pk), self);
111
111
 
112
112
  MessagePack_Buffer_set_options(PACKER_BUFFER_(pk), io, options);
113
113
 
@@ -233,7 +233,12 @@ static VALUE Packer_write_extension(VALUE self, VALUE obj)
233
233
  msgpack_packer_t *pk = MessagePack_Packer_get(self);
234
234
  Check_Type(obj, T_STRUCT);
235
235
 
236
- 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);
237
242
  if(ext_type < -128 || ext_type > 127) {
238
243
  rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
239
244
  }
@@ -347,7 +352,7 @@ static VALUE Packer_registered_types_internal(VALUE self)
347
352
  return rb_hash_new();
348
353
  }
349
354
 
350
- 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)
351
356
  {
352
357
  if (OBJ_FROZEN(self)) {
353
358
  rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Packer");
@@ -355,38 +360,12 @@ static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
355
360
 
356
361
  msgpack_packer_t *pk = MessagePack_Packer_get(self);
357
362
 
358
- int ext_type;
359
- VALUE ext_module;
360
- VALUE proc;
361
- VALUE arg;
362
-
363
- switch (argc) {
364
- case 2:
365
- /* register_type(0x7f, Time) {|obj| block... } */
366
- rb_need_block();
367
- proc = rb_block_lambda();
368
- arg = proc;
369
- break;
370
- case 3:
371
- /* register_type(0x7f, Time, :to_msgpack_ext) */
372
- arg = argv[2];
373
- proc = rb_funcall(arg, rb_intern("to_proc"), 0);
374
- break;
375
- default:
376
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 2..3)", argc);
377
- }
378
-
379
- ext_type = NUM2INT(argv[0]);
363
+ int ext_type = NUM2INT(rb_ext_type);
380
364
  if(ext_type < -128 || ext_type > 127) {
381
365
  rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
382
366
  }
383
367
 
384
- ext_module = argv[1];
385
- if(rb_type(ext_module) != T_MODULE && rb_type(ext_module) != T_CLASS) {
386
- rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
387
- }
388
-
389
- 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);
390
369
 
391
370
  if (ext_module == rb_cSymbol) {
392
371
  pk->has_symbol_ext_type = true;
@@ -419,10 +398,6 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
419
398
  s_write = rb_intern("write");
420
399
 
421
400
  sym_compatibility_mode = ID2SYM(rb_intern("compatibility_mode"));
422
-
423
- msgpack_packer_static_init();
424
- msgpack_packer_ext_registry_static_init();
425
-
426
401
  cMessagePack_Packer = rb_define_class_under(mMessagePack, "Packer", rb_cObject);
427
402
 
428
403
  rb_define_alloc_func(cMessagePack_Packer, MessagePack_Packer_alloc);
@@ -461,7 +436,7 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
461
436
  rb_define_method(cMessagePack_Packer, "to_a", Packer_to_a, 0);
462
437
 
463
438
  rb_define_private_method(cMessagePack_Packer, "registered_types_internal", Packer_registered_types_internal, 0);
464
- rb_define_method(cMessagePack_Packer, "register_type", Packer_register_type, -1);
439
+ rb_define_method(cMessagePack_Packer, "register_type_internal", Packer_register_type_internal, 3);
465
440
 
466
441
  rb_define_method(cMessagePack_Packer, "full_pack", Packer_full_pack, 0);
467
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
 
@@ -19,17 +19,15 @@
19
19
  #include "unpacker.h"
20
20
  #include "rmem.h"
21
21
  #include "extension_value_class.h"
22
+ #include <assert.h>
22
23
 
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
- );
24
+ #if !defined(HAVE_RB_PROC_CALL_WITH_BLOCK)
25
+ #define rb_proc_call_with_block(recv, argc, argv, block) rb_funcallv(recv, rb_intern("call"), argc, argv)
26
+ #endif
27
27
 
28
28
  static int RAW_TYPE_STRING = 256;
29
29
  static int RAW_TYPE_BINARY = 257;
30
30
 
31
- static ID s_call;
32
-
33
31
  static msgpack_rmem_t s_stack_rmem;
34
32
 
35
33
  #if !defined(HAVE_RB_HASH_NEW_CAPA)
@@ -41,9 +39,9 @@ static inline VALUE rb_hash_new_capa(long capa)
41
39
 
42
40
  void msgpack_unpacker_static_init(void)
43
41
  {
44
- msgpack_rmem_init(&s_stack_rmem);
42
+ assert(sizeof(msgpack_unpacker_stack_entry_t) * MSGPACK_UNPACKER_STACK_CAPACITY <= MSGPACK_RMEM_PAGE_SIZE);
45
43
 
46
- s_call = rb_intern("call");
44
+ msgpack_rmem_init(&s_stack_rmem);
47
45
  }
48
46
 
49
47
  void msgpack_unpacker_static_destroy(void)
@@ -180,7 +178,8 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
180
178
 
181
179
  if(proc != Qnil) {
182
180
  VALUE obj;
183
- obj = rb_funcall(proc, s_call, 1, str == Qnil ? rb_str_buf_new(0) : str);
181
+ VALUE arg = (str == Qnil ? rb_str_buf_new(0) : str);
182
+ obj = rb_proc_call_with_block(proc, 1, &arg, Qnil);
184
183
  return object_complete(uk, obj);
185
184
  }
186
185
 
@@ -310,7 +309,7 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
310
309
  child_stack->parent = uk->stack;
311
310
  uk->stack = child_stack;
312
311
 
313
- obj = rb_funcall(proc, s_call, 1, uk->self);
312
+ obj = rb_proc_call_with_block(proc, 1, &uk->self, Qnil);
314
313
 
315
314
  uk->stack = child_stack->parent;
316
315
  _msgpack_unpacker_free_stack(child_stack);
@@ -346,43 +346,19 @@ static VALUE Unpacker_registered_types_internal(VALUE self)
346
346
  return mapping;
347
347
  }
348
348
 
349
- static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
349
+ static VALUE Unpacker_register_type_internal(VALUE self, VALUE rb_ext_type, VALUE ext_module, VALUE proc)
350
350
  {
351
351
  if (OBJ_FROZEN(self)) {
352
352
  rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Unpacker");
353
353
  }
354
354
 
355
- msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
356
-
357
- int ext_type;
358
- VALUE proc;
359
- VALUE arg;
360
- VALUE ext_module;
361
-
362
- switch (argc) {
363
- case 1:
364
- /* register_type(0x7f) {|data| block... } */
365
- rb_need_block();
366
- proc = rb_block_lambda();
367
- arg = proc;
368
- ext_module = Qnil;
369
- break;
370
- case 3:
371
- /* register_type(0x7f, Time, :from_msgpack_ext) */
372
- ext_module = argv[1];
373
- arg = argv[2];
374
- proc = rb_obj_method(ext_module, arg);
375
- break;
376
- default:
377
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 3)", argc);
378
- }
379
-
380
- ext_type = NUM2INT(argv[0]);
355
+ int ext_type = NUM2INT(rb_ext_type);
381
356
  if(ext_type < -128 || ext_type > 127) {
382
357
  rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
383
358
  }
384
359
 
385
- msgpack_unpacker_ext_registry_put(&uk->ext_registry, ext_module, ext_type, 0, proc, arg);
360
+ msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
361
+ msgpack_unpacker_ext_registry_put(self, &uk->ext_registry, ext_module, ext_type, 0, proc);
386
362
 
387
363
  return Qnil;
388
364
  }
@@ -415,7 +391,6 @@ VALUE MessagePack_Unpacker_new(int argc, VALUE* argv)
415
391
  void MessagePack_Unpacker_module_init(VALUE mMessagePack)
416
392
  {
417
393
  msgpack_unpacker_static_init();
418
- msgpack_unpacker_ext_registry_static_init();
419
394
 
420
395
  mTypeError = rb_define_module_under(mMessagePack, "TypeError");
421
396
 
@@ -456,7 +431,7 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
456
431
  rb_define_method(cMessagePack_Unpacker, "reset", Unpacker_reset, 0);
457
432
 
458
433
  rb_define_private_method(cMessagePack_Unpacker, "registered_types_internal", Unpacker_registered_types_internal, 0);
459
- rb_define_method(cMessagePack_Unpacker, "register_type", Unpacker_register_type, -1);
434
+ rb_define_private_method(cMessagePack_Unpacker, "register_type_internal", Unpacker_register_type_internal, 3);
460
435
 
461
436
  rb_define_method(cMessagePack_Unpacker, "full_unpack", Unpacker_full_unpack, 0);
462
437
  }
@@ -18,19 +18,6 @@
18
18
 
19
19
  #include "unpacker_ext_registry.h"
20
20
 
21
- static ID s_call;
22
- static ID s_dup;
23
-
24
- void msgpack_unpacker_ext_registry_static_init(void)
25
- {
26
- s_call = rb_intern("call");
27
- s_dup = rb_intern("dup");
28
- }
29
-
30
-
31
- void msgpack_unpacker_ext_registry_static_destroy(void)
32
- { }
33
-
34
21
  void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg)
35
22
  {
36
23
  if (ukrg) {
@@ -76,11 +63,12 @@ void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg
76
63
  }
77
64
  }
78
65
 
79
- void msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t** ukrg,
80
- VALUE ext_module, int ext_type, int flags, VALUE proc, VALUE arg)
66
+ void msgpack_unpacker_ext_registry_put(VALUE owner, msgpack_unpacker_ext_registry_t** ukrg,
67
+ VALUE ext_module, int ext_type, int flags, VALUE proc)
81
68
  {
82
69
  msgpack_unpacker_ext_registry_t* ext_registry = msgpack_unpacker_ext_registry_cow(*ukrg);
83
70
 
84
- ext_registry->array[ext_type + 128] = rb_ary_new3(4, ext_module, proc, arg, INT2FIX(flags));
71
+ VALUE entry = rb_ary_new3(3, ext_module, proc, INT2FIX(flags));
72
+ RB_OBJ_WRITE(owner, &ext_registry->array[ext_type + 128], entry);
85
73
  *ukrg = ext_registry;
86
74
  }
@@ -31,10 +31,6 @@ struct msgpack_unpacker_ext_registry_t {
31
31
  VALUE array[256];
32
32
  };
33
33
 
34
- void msgpack_unpacker_ext_registry_static_init(void);
35
-
36
- void msgpack_unpacker_ext_registry_static_destroy(void);
37
-
38
34
  void msgpack_unpacker_ext_registry_release(msgpack_unpacker_ext_registry_t* ukrg);
39
35
 
40
36
  static inline void msgpack_unpacker_ext_registry_borrow(msgpack_unpacker_ext_registry_t* src, msgpack_unpacker_ext_registry_t** dst)
@@ -47,8 +43,8 @@ static inline void msgpack_unpacker_ext_registry_borrow(msgpack_unpacker_ext_reg
47
43
 
48
44
  void msgpack_unpacker_ext_registry_mark(msgpack_unpacker_ext_registry_t* ukrg);
49
45
 
50
- void msgpack_unpacker_ext_registry_put(msgpack_unpacker_ext_registry_t** ukrg,
51
- VALUE ext_module, int ext_type, int flags, VALUE proc, VALUE arg);
46
+ void msgpack_unpacker_ext_registry_put(VALUE owner, msgpack_unpacker_ext_registry_t** ukrg,
47
+ VALUE ext_module, int ext_type, int flags, VALUE proc);
52
48
 
53
49
  static inline VALUE msgpack_unpacker_ext_registry_lookup(msgpack_unpacker_ext_registry_t* ukrg,
54
50
  int ext_type, int* ext_flags_result)
@@ -56,7 +52,7 @@ static inline VALUE msgpack_unpacker_ext_registry_lookup(msgpack_unpacker_ext_re
56
52
  if (ukrg) {
57
53
  VALUE entry = ukrg->array[ext_type + 128];
58
54
  if (entry != Qnil) {
59
- *ext_flags_result = FIX2INT(rb_ary_entry(entry, 3));
55
+ *ext_flags_result = FIX2INT(rb_ary_entry(entry, 2));
60
56
  return rb_ary_entry(entry, 1);
61
57
  }
62
58
  }