msgpack 1.7.1 → 1.8.0
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.
- checksums.yaml +4 -4
- data/ChangeLog +22 -0
- data/README.md +21 -12
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +5 -9
- data/ext/java/org/msgpack/jruby/Factory.java +7 -50
- data/ext/java/org/msgpack/jruby/Packer.java +3 -20
- data/ext/java/org/msgpack/jruby/Unpacker.java +8 -24
- data/ext/msgpack/buffer.c +12 -9
- data/ext/msgpack/buffer.h +134 -28
- data/ext/msgpack/buffer_class.c +72 -1
- data/ext/msgpack/buffer_class.h +1 -0
- data/ext/msgpack/extconf.rb +6 -5
- data/ext/msgpack/factory_class.c +23 -60
- data/ext/msgpack/packer.c +12 -14
- data/ext/msgpack/packer.h +24 -21
- data/ext/msgpack/packer_class.c +6 -36
- data/ext/msgpack/packer_ext_registry.c +31 -28
- data/ext/msgpack/packer_ext_registry.h +10 -14
- data/ext/msgpack/unpacker.c +196 -90
- data/ext/msgpack/unpacker.h +18 -8
- data/ext/msgpack/unpacker_class.c +32 -47
- data/ext/msgpack/unpacker_ext_registry.c +4 -16
- data/ext/msgpack/unpacker_ext_registry.h +3 -7
- data/lib/msgpack/factory.rb +49 -10
- data/lib/msgpack/packer.rb +6 -1
- data/lib/msgpack/unpacker.rb +10 -1
- data/lib/msgpack/version.rb +1 -1
- data/msgpack.gemspec +2 -0
- metadata +5 -7
data/ext/msgpack/extconf.rb
CHANGED
@@ -1,20 +1,21 @@
|
|
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)
|
6
|
+
have_func("rb_gc_mark_locations", "ruby.h") # Missing on TruffleRuby
|
7
7
|
|
8
8
|
append_cflags([
|
9
9
|
"-fvisibility=hidden",
|
10
10
|
"-I..",
|
11
11
|
"-Wall",
|
12
|
-
"-O3",
|
13
12
|
"-std=gnu99"
|
14
13
|
])
|
15
|
-
append_cflags(RbConfig::CONFIG["debugflags"]) if RbConfig::CONFIG["debugflags"]
|
16
14
|
|
17
|
-
|
15
|
+
if ENV["MSGPACK_DEBUG"]
|
16
|
+
append_cflags(RbConfig::CONFIG["debugflags"]) if RbConfig::CONFIG["debugflags"]
|
17
|
+
append_cflags("-DRUBY_DEBUG=1")
|
18
|
+
end
|
18
19
|
|
19
20
|
if RUBY_VERSION.start_with?('3.0.') && RUBY_VERSION <= '3.0.5'
|
20
21
|
# https://bugs.ruby-lang.org/issues/18772
|
data/ext/msgpack/factory_class.c
CHANGED
@@ -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
|
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
|
-
|
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]
|
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,72 +200,35 @@ static VALUE Factory_registered_types_internal(VALUE self)
|
|
200
200
|
);
|
201
201
|
}
|
202
202
|
|
203
|
-
static VALUE
|
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
|
-
|
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
|
215
|
-
rb_raise(
|
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
|
-
|
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, unpacker: 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
|
-
}
|
213
|
+
int flags = 0;
|
230
214
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
215
|
+
VALUE packer_proc = Qnil;
|
216
|
+
VALUE unpacker_proc = Qnil;
|
217
|
+
if(!NIL_P(options)) {
|
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")));
|
236
221
|
}
|
237
222
|
|
238
|
-
if (
|
239
|
-
|
223
|
+
if (OBJ_FROZEN(self)) {
|
224
|
+
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Factory");
|
240
225
|
}
|
241
226
|
|
242
|
-
ext_type = NUM2INT(
|
227
|
+
int ext_type = NUM2INT(rb_ext_type);
|
243
228
|
if(ext_type < -128 || ext_type > 127) {
|
244
229
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
245
230
|
}
|
246
231
|
|
247
|
-
ext_module = argv[1];
|
248
|
-
if(rb_type(ext_module) != T_MODULE && rb_type(ext_module) != T_CLASS) {
|
249
|
-
rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
|
250
|
-
}
|
251
|
-
|
252
|
-
packer_proc = Qnil;
|
253
|
-
unpacker_proc = Qnil;
|
254
|
-
|
255
|
-
if(packer_arg != Qnil) {
|
256
|
-
packer_proc = rb_funcall(packer_arg, rb_intern("to_proc"), 0);
|
257
|
-
}
|
258
|
-
|
259
|
-
if(unpacker_arg != Qnil) {
|
260
|
-
if(rb_type(unpacker_arg) == T_SYMBOL || rb_type(unpacker_arg) == T_STRING) {
|
261
|
-
unpacker_proc = rb_obj_method(ext_module, unpacker_arg);
|
262
|
-
} else if (rb_respond_to(unpacker_arg, rb_intern("call"))) {
|
263
|
-
unpacker_proc = unpacker_arg;
|
264
|
-
} else {
|
265
|
-
unpacker_proc = rb_funcall(unpacker_arg, rb_intern("method"), 1, ID2SYM(rb_intern("call")));
|
266
|
-
}
|
267
|
-
}
|
268
|
-
|
269
232
|
if(ext_module == rb_cSymbol) {
|
270
233
|
if(NIL_P(options) || RTEST(rb_hash_aref(options, ID2SYM(rb_intern("packer"))))) {
|
271
234
|
fc->has_symbol_ext_type = true;
|
@@ -289,8 +252,8 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
|
|
289
252
|
}
|
290
253
|
}
|
291
254
|
|
292
|
-
msgpack_packer_ext_registry_put(&fc->pkrg, ext_module, ext_type, flags, packer_proc
|
293
|
-
msgpack_unpacker_ext_registry_put(&fc->ukrg, ext_module, ext_type, flags, unpacker_proc
|
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);
|
294
257
|
|
295
258
|
return Qnil;
|
296
259
|
}
|
@@ -309,5 +272,5 @@ void MessagePack_Factory_module_init(VALUE mMessagePack)
|
|
309
272
|
rb_define_method(cMessagePack_Factory, "unpacker", MessagePack_Factory_unpacker, -1);
|
310
273
|
|
311
274
|
rb_define_private_method(cMessagePack_Factory, "registered_types_internal", Factory_registered_types_internal, 0);
|
312
|
-
|
275
|
+
rb_define_private_method(cMessagePack_Factory, "register_type_internal", Factory_register_type_internal, 3);
|
313
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
|
-
|
22
|
-
|
23
|
-
|
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
|
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
|
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 =
|
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
@@ -25,21 +25,26 @@
|
|
25
25
|
#define MSGPACK_PACKER_IO_FLUSH_THRESHOLD_TO_WRITE_STRING_BODY (1024)
|
26
26
|
#endif
|
27
27
|
|
28
|
+
#ifndef UNREACHABLE_RETURN
|
29
|
+
// Ruby 2.5
|
30
|
+
#define UNREACHABLE_RETURN() return
|
31
|
+
#endif
|
32
|
+
|
28
33
|
struct msgpack_packer_t;
|
29
34
|
typedef struct msgpack_packer_t msgpack_packer_t;
|
30
35
|
|
31
36
|
struct msgpack_packer_t {
|
32
37
|
msgpack_buffer_t buffer;
|
33
38
|
|
34
|
-
bool compatibility_mode;
|
35
|
-
bool has_bigint_ext_type;
|
36
|
-
bool has_symbol_ext_type;
|
37
|
-
|
38
39
|
ID to_msgpack_method;
|
39
40
|
VALUE to_msgpack_arg;
|
40
41
|
|
41
42
|
VALUE buffer_ref;
|
42
43
|
|
44
|
+
bool compatibility_mode;
|
45
|
+
bool has_bigint_ext_type;
|
46
|
+
bool has_symbol_ext_type;
|
47
|
+
|
43
48
|
/* options */
|
44
49
|
bool comaptibility_mode;
|
45
50
|
msgpack_packer_ext_registry_t ext_registry;
|
@@ -47,10 +52,6 @@ struct msgpack_packer_t {
|
|
47
52
|
|
48
53
|
#define PACKER_BUFFER_(pk) (&(pk)->buffer)
|
49
54
|
|
50
|
-
void msgpack_packer_static_init(void);
|
51
|
-
|
52
|
-
void msgpack_packer_static_destroy(void);
|
53
|
-
|
54
55
|
void msgpack_packer_init(msgpack_packer_t* pk);
|
55
56
|
|
56
57
|
void msgpack_packer_destroy(msgpack_packer_t* pk);
|
@@ -408,27 +409,33 @@ static inline bool msgpack_packer_is_utf8_compat_string(VALUE v, int encindex)
|
|
408
409
|
{
|
409
410
|
return encindex == msgpack_rb_encindex_utf8
|
410
411
|
|| encindex == msgpack_rb_encindex_usascii
|
411
|
-
||
|
412
|
+
|| ENC_CODERANGE_ASCIIONLY(v);
|
412
413
|
}
|
413
414
|
|
414
415
|
static inline void msgpack_packer_write_string_value(msgpack_packer_t* pk, VALUE v)
|
415
416
|
{
|
416
|
-
|
417
|
-
|
418
|
-
if(len >
|
419
|
-
|
420
|
-
|
417
|
+
long len = RSTRING_LEN(v);
|
418
|
+
|
419
|
+
if(RB_UNLIKELY(len > 0xffffffffL)) {
|
420
|
+
rb_raise(rb_eArgError, "size of string is too long to pack: %lu bytes should be <= %ld", len, 0xffffffffL);
|
421
|
+
UNREACHABLE_RETURN();
|
421
422
|
}
|
422
423
|
|
423
|
-
|
424
|
-
|
424
|
+
if (RB_UNLIKELY(pk->compatibility_mode)) {
|
425
|
+
msgpack_packer_write_raw_header(pk, (unsigned int)len);
|
426
|
+
msgpack_buffer_append_string(PACKER_BUFFER_(pk), v);
|
427
|
+
return;
|
428
|
+
}
|
429
|
+
|
430
|
+
int encindex = ENCODING_GET_INLINED(v);
|
431
|
+
if(msgpack_packer_is_binary(v, encindex)) {
|
425
432
|
/* write ASCII-8BIT string using Binary type */
|
426
433
|
msgpack_packer_write_bin_header(pk, (unsigned int)len);
|
427
434
|
msgpack_buffer_append_string(PACKER_BUFFER_(pk), v);
|
428
435
|
} else {
|
429
436
|
/* write UTF-8, US-ASCII, or 7bit-safe ascii-compatible string using String type directly */
|
430
437
|
/* in compatibility mode, packer packs String values as is */
|
431
|
-
if(!
|
438
|
+
if(RB_UNLIKELY(!msgpack_packer_is_utf8_compat_string(v, encindex))) {
|
432
439
|
/* transcode other strings to UTF-8 and write using String type */
|
433
440
|
VALUE enc = rb_enc_from_encoding(rb_utf8_encoding()); /* rb_enc_from_encoding_index is not extern */
|
434
441
|
v = rb_str_encode(v, enc, 0, Qnil);
|
@@ -457,11 +464,7 @@ static inline void msgpack_packer_write_symbol_value(msgpack_packer_t* pk, VALUE
|
|
457
464
|
|
458
465
|
static inline void msgpack_packer_write_fixnum_value(msgpack_packer_t* pk, VALUE v)
|
459
466
|
{
|
460
|
-
#ifdef JRUBY
|
461
|
-
msgpack_packer_write_long(pk, FIXNUM_P(v) ? FIX2LONG(v) : rb_num2ll(v));
|
462
|
-
#else
|
463
467
|
msgpack_packer_write_long(pk, FIX2LONG(v));
|
464
|
-
#endif
|
465
468
|
}
|
466
469
|
|
467
470
|
static inline void msgpack_packer_write_bignum_value(msgpack_packer_t* pk, VALUE v)
|
data/ext/msgpack/packer_class.c
CHANGED
@@ -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 =
|
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
|
|
@@ -352,7 +352,7 @@ static VALUE Packer_registered_types_internal(VALUE self)
|
|
352
352
|
return rb_hash_new();
|
353
353
|
}
|
354
354
|
|
355
|
-
static VALUE
|
355
|
+
static VALUE Packer_register_type_internal(VALUE self, VALUE rb_ext_type, VALUE ext_module, VALUE proc)
|
356
356
|
{
|
357
357
|
if (OBJ_FROZEN(self)) {
|
358
358
|
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Packer");
|
@@ -360,38 +360,12 @@ static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
|
|
360
360
|
|
361
361
|
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
362
362
|
|
363
|
-
int ext_type;
|
364
|
-
VALUE ext_module;
|
365
|
-
VALUE proc;
|
366
|
-
VALUE arg;
|
367
|
-
|
368
|
-
switch (argc) {
|
369
|
-
case 2:
|
370
|
-
/* register_type(0x7f, Time) {|obj| block... } */
|
371
|
-
rb_need_block();
|
372
|
-
proc = rb_block_lambda();
|
373
|
-
arg = proc;
|
374
|
-
break;
|
375
|
-
case 3:
|
376
|
-
/* register_type(0x7f, Time, :to_msgpack_ext) */
|
377
|
-
arg = argv[2];
|
378
|
-
proc = rb_funcall(arg, rb_intern("to_proc"), 0);
|
379
|
-
break;
|
380
|
-
default:
|
381
|
-
rb_raise(rb_eArgError, "wrong number of arguments (%d for 2..3)", argc);
|
382
|
-
}
|
383
|
-
|
384
|
-
ext_type = NUM2INT(argv[0]);
|
363
|
+
int ext_type = NUM2INT(rb_ext_type);
|
385
364
|
if(ext_type < -128 || ext_type > 127) {
|
386
365
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
387
366
|
}
|
388
367
|
|
389
|
-
ext_module
|
390
|
-
if(rb_type(ext_module) != T_MODULE && rb_type(ext_module) != T_CLASS) {
|
391
|
-
rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
|
392
|
-
}
|
393
|
-
|
394
|
-
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);
|
395
369
|
|
396
370
|
if (ext_module == rb_cSymbol) {
|
397
371
|
pk->has_symbol_ext_type = true;
|
@@ -424,10 +398,6 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
|
|
424
398
|
s_write = rb_intern("write");
|
425
399
|
|
426
400
|
sym_compatibility_mode = ID2SYM(rb_intern("compatibility_mode"));
|
427
|
-
|
428
|
-
msgpack_packer_static_init();
|
429
|
-
msgpack_packer_ext_registry_static_init();
|
430
|
-
|
431
401
|
cMessagePack_Packer = rb_define_class_under(mMessagePack, "Packer", rb_cObject);
|
432
402
|
|
433
403
|
rb_define_alloc_func(cMessagePack_Packer, MessagePack_Packer_alloc);
|
@@ -466,7 +436,7 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
|
|
466
436
|
rb_define_method(cMessagePack_Packer, "to_a", Packer_to_a, 0);
|
467
437
|
|
468
438
|
rb_define_private_method(cMessagePack_Packer, "registered_types_internal", Packer_registered_types_internal, 0);
|
469
|
-
rb_define_method(cMessagePack_Packer, "
|
439
|
+
rb_define_method(cMessagePack_Packer, "register_type_internal", Packer_register_type_internal, 3);
|
470
440
|
|
471
441
|
rb_define_method(cMessagePack_Packer, "full_pack", Packer_full_pack, 0);
|
472
442
|
}
|
@@ -18,20 +18,10 @@
|
|
18
18
|
|
19
19
|
#include "packer_ext_registry.h"
|
20
20
|
|
21
|
-
|
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
|
34
|
-
pkrg->cache
|
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
|
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)
|
47
|
-
|
48
|
-
|
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
|
-
|
51
|
-
dst->
|
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
|
57
|
-
|
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
|
-
|
60
|
-
|
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
|
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
|
-
|
69
|
-
|
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
|
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
|
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
|
49
|
-
|
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,
|
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,
|
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,
|
133
|
+
*ext_flags_result = FIX2INT(rb_ary_entry(superclass_type, 2));
|
138
134
|
return rb_ary_entry(superclass_type, 1);
|
139
135
|
}
|
140
136
|
|