msgpack 1.6.1 → 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.
- checksums.yaml +4 -4
- data/ChangeLog +19 -0
- data/README.md +27 -0
- data/ext/java/org/msgpack/jruby/Buffer.java +3 -3
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +7 -11
- data/ext/java/org/msgpack/jruby/ExtensionValue.java +1 -1
- data/ext/java/org/msgpack/jruby/Factory.java +11 -50
- data/ext/java/org/msgpack/jruby/Packer.java +9 -24
- data/ext/java/org/msgpack/jruby/Unpacker.java +15 -32
- data/ext/msgpack/buffer.c +16 -17
- data/ext/msgpack/buffer.h +2 -8
- data/ext/msgpack/buffer_class.c +72 -1
- data/ext/msgpack/buffer_class.h +1 -0
- data/ext/msgpack/extconf.rb +16 -26
- data/ext/msgpack/factory_class.c +27 -61
- data/ext/msgpack/packer.c +12 -14
- data/ext/msgpack/packer.h +0 -4
- data/ext/msgpack/packer_class.c +16 -37
- data/ext/msgpack/packer_ext_registry.c +31 -28
- data/ext/msgpack/packer_ext_registry.h +10 -14
- data/ext/msgpack/rmem.c +3 -4
- data/ext/msgpack/unpacker.c +11 -25
- data/ext/msgpack/unpacker.h +0 -4
- data/ext/msgpack/unpacker_class.c +9 -42
- data/ext/msgpack/unpacker_ext_registry.c +4 -16
- data/ext/msgpack/unpacker_ext_registry.h +3 -7
- data/lib/msgpack/factory.rb +90 -63
- data/lib/msgpack/packer.rb +6 -1
- data/lib/msgpack/unpacker.rb +10 -1
- data/lib/msgpack/version.rb +1 -1
- data/msgpack.gemspec +1 -1
- metadata +4 -4
data/ext/msgpack/extconf.rb
CHANGED
@@ -1,19 +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
|
-
|
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"]
|
9
15
|
|
10
|
-
|
11
|
-
$CFLAGS << %[ -I.. -Wall -O3 #{RbConfig::CONFIG["debugflags"]} -std=gnu99]
|
12
|
-
end
|
16
|
+
append_cflags("-DRUBY_DEBUG=1") if ENV["MSGPACK_DEBUG"]
|
13
17
|
|
14
18
|
if RUBY_VERSION.start_with?('3.0.') && RUBY_VERSION <= '3.0.5'
|
15
19
|
# https://bugs.ruby-lang.org/issues/18772
|
16
|
-
|
20
|
+
append_cflags("-DRB_ENC_INTERNED_STR_NULL_CHECK=1")
|
17
21
|
end
|
18
22
|
|
19
23
|
# checking if Hash#[]= (rb_hash_aset) dedupes string keys (Ruby 2.6+)
|
@@ -23,35 +27,21 @@ r = rand.to_s
|
|
23
27
|
h[%W(#{r}).join('')] = :foo
|
24
28
|
x[%W(#{r}).join('')] = :foo
|
25
29
|
if x.keys[0].equal?(h.keys[0])
|
26
|
-
|
30
|
+
append_cflags("-DHASH_ASET_DEDUPE=1")
|
27
31
|
else
|
28
|
-
|
29
|
-
end
|
30
|
-
|
31
|
-
|
32
|
-
# checking if String#-@ (str_uminus) dedupes... ' (Ruby 2.5+)
|
33
|
-
begin
|
34
|
-
a = -(%w(t e s t).join)
|
35
|
-
b = -(%w(t e s t).join)
|
36
|
-
if a.equal?(b)
|
37
|
-
$CFLAGS << ' -DSTR_UMINUS_DEDUPE=1 '
|
38
|
-
else
|
39
|
-
$CFLAGS += ' -DSTR_UMINUS_DEDUPE=0 '
|
40
|
-
end
|
41
|
-
rescue NoMethodError
|
42
|
-
$CFLAGS << ' -DSTR_UMINUS_DEDUPE=0 '
|
32
|
+
append_cflags("-DHASH_ASET_DEDUPE=0")
|
43
33
|
end
|
44
34
|
|
45
35
|
# checking if String#-@ (str_uminus) directly interns frozen strings... ' (Ruby 3.0+)
|
46
36
|
begin
|
47
37
|
s = rand.to_s.freeze
|
48
38
|
if (-s).equal?(s) && (-s.dup).equal?(s)
|
49
|
-
|
39
|
+
append_cflags("-DSTR_UMINUS_DEDUPE_FROZEN=1")
|
50
40
|
else
|
51
|
-
|
41
|
+
append_cflags("-DSTR_UMINUS_DEDUPE_FROZEN=0")
|
52
42
|
end
|
53
43
|
rescue NoMethodError
|
54
|
-
|
44
|
+
append_cflags("-DSTR_UMINUS_DEDUPE_FROZEN=0")
|
55
45
|
end
|
56
46
|
|
57
47
|
if warnflags = CONFIG['warnflags']
|
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,73 +200,39 @@ 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, 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
|
-
|
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
|
-
|
242
|
-
|
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
|
-
|
259
|
-
|
260
|
-
|
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
|
-
|
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
|
290
|
-
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);
|
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
|
-
|
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
|
-
|
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
@@ -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);
|
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
|
|
@@ -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
|
-
|
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,42 +352,20 @@ static VALUE Packer_registered_types_internal(VALUE self)
|
|
347
352
|
return rb_hash_new();
|
348
353
|
}
|
349
354
|
|
350
|
-
static VALUE
|
355
|
+
static VALUE Packer_register_type_internal(VALUE self, VALUE rb_ext_type, VALUE ext_module, VALUE proc)
|
351
356
|
{
|
352
|
-
|
353
|
-
|
354
|
-
int ext_type;
|
355
|
-
VALUE ext_module;
|
356
|
-
VALUE proc;
|
357
|
-
VALUE arg;
|
358
|
-
|
359
|
-
switch (argc) {
|
360
|
-
case 2:
|
361
|
-
/* register_type(0x7f, Time) {|obj| block... } */
|
362
|
-
rb_need_block();
|
363
|
-
proc = rb_block_lambda();
|
364
|
-
arg = proc;
|
365
|
-
break;
|
366
|
-
case 3:
|
367
|
-
/* register_type(0x7f, Time, :to_msgpack_ext) */
|
368
|
-
arg = argv[2];
|
369
|
-
proc = rb_funcall(arg, rb_intern("to_proc"), 0);
|
370
|
-
break;
|
371
|
-
default:
|
372
|
-
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");
|
373
359
|
}
|
374
360
|
|
375
|
-
|
361
|
+
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
362
|
+
|
363
|
+
int ext_type = NUM2INT(rb_ext_type);
|
376
364
|
if(ext_type < -128 || ext_type > 127) {
|
377
365
|
rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
|
378
366
|
}
|
379
367
|
|
380
|
-
ext_module
|
381
|
-
if(rb_type(ext_module) != T_MODULE && rb_type(ext_module) != T_CLASS) {
|
382
|
-
rb_raise(rb_eArgError, "expected Module/Class but found %s.", rb_obj_classname(ext_module));
|
383
|
-
}
|
384
|
-
|
385
|
-
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);
|
386
369
|
|
387
370
|
if (ext_module == rb_cSymbol) {
|
388
371
|
pk->has_symbol_ext_type = true;
|
@@ -415,10 +398,6 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
|
|
415
398
|
s_write = rb_intern("write");
|
416
399
|
|
417
400
|
sym_compatibility_mode = ID2SYM(rb_intern("compatibility_mode"));
|
418
|
-
|
419
|
-
msgpack_packer_static_init();
|
420
|
-
msgpack_packer_ext_registry_static_init();
|
421
|
-
|
422
401
|
cMessagePack_Packer = rb_define_class_under(mMessagePack, "Packer", rb_cObject);
|
423
402
|
|
424
403
|
rb_define_alloc_func(cMessagePack_Packer, MessagePack_Packer_alloc);
|
@@ -457,7 +436,7 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
|
|
457
436
|
rb_define_method(cMessagePack_Packer, "to_a", Packer_to_a, 0);
|
458
437
|
|
459
438
|
rb_define_private_method(cMessagePack_Packer, "registered_types_internal", Packer_registered_types_internal, 0);
|
460
|
-
rb_define_method(cMessagePack_Packer, "
|
439
|
+
rb_define_method(cMessagePack_Packer, "register_type_internal", Packer_register_type_internal, 3);
|
461
440
|
|
462
441
|
rb_define_method(cMessagePack_Packer, "full_pack", Packer_full_pack, 0);
|
463
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
|
|
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
|
69
|
-
|
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
|
|
data/ext/msgpack/unpacker.c
CHANGED
@@ -19,20 +19,16 @@
|
|
19
19
|
#include "unpacker.h"
|
20
20
|
#include "rmem.h"
|
21
21
|
#include "extension_value_class.h"
|
22
|
+
#include <assert.h>
|
22
23
|
|
23
|
-
#if !defined(
|
24
|
-
|
25
|
-
#define UNPACKER_STACK_RMEM
|
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
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
|
-
#ifdef UNPACKER_STACK_RMEM
|
34
31
|
static msgpack_rmem_t s_stack_rmem;
|
35
|
-
#endif
|
36
32
|
|
37
33
|
#if !defined(HAVE_RB_HASH_NEW_CAPA)
|
38
34
|
static inline VALUE rb_hash_new_capa(long capa)
|
@@ -43,18 +39,14 @@ static inline VALUE rb_hash_new_capa(long capa)
|
|
43
39
|
|
44
40
|
void msgpack_unpacker_static_init(void)
|
45
41
|
{
|
46
|
-
|
47
|
-
msgpack_rmem_init(&s_stack_rmem);
|
48
|
-
#endif
|
42
|
+
assert(sizeof(msgpack_unpacker_stack_entry_t) * MSGPACK_UNPACKER_STACK_CAPACITY <= MSGPACK_RMEM_PAGE_SIZE);
|
49
43
|
|
50
|
-
|
44
|
+
msgpack_rmem_init(&s_stack_rmem);
|
51
45
|
}
|
52
46
|
|
53
47
|
void msgpack_unpacker_static_destroy(void)
|
54
48
|
{
|
55
|
-
#ifdef UNPACKER_STACK_RMEM
|
56
49
|
msgpack_rmem_destroy(&s_stack_rmem);
|
57
|
-
#endif
|
58
50
|
}
|
59
51
|
|
60
52
|
#define HEAD_BYTE_REQUIRED 0xc1
|
@@ -62,13 +54,8 @@ void msgpack_unpacker_static_destroy(void)
|
|
62
54
|
static inline msgpack_unpacker_stack_t* _msgpack_unpacker_new_stack(void) {
|
63
55
|
msgpack_unpacker_stack_t *stack = ZALLOC(msgpack_unpacker_stack_t);
|
64
56
|
stack->capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
65
|
-
#ifdef UNPACKER_STACK_RMEM
|
66
57
|
stack->data = msgpack_rmem_alloc(&s_stack_rmem);
|
67
58
|
/*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
|
68
|
-
#else
|
69
|
-
/*uk->stack = calloc(MSGPACK_UNPACKER_STACK_CAPACITY, sizeof(msgpack_unpacker_stack_entry_t));*/
|
70
|
-
stack->data = xmalloc(MSGPACK_UNPACKER_STACK_CAPACITY * sizeof(msgpack_unpacker_stack_entry_t));
|
71
|
-
#endif
|
72
59
|
return stack;
|
73
60
|
}
|
74
61
|
|
@@ -85,11 +72,9 @@ void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
|
|
85
72
|
}
|
86
73
|
|
87
74
|
static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
xfree(stack->data);
|
92
|
-
#endif
|
75
|
+
if (!msgpack_rmem_free(&s_stack_rmem, stack->data)) {
|
76
|
+
rb_bug("Failed to free an rmem pointer, memory leak?");
|
77
|
+
}
|
93
78
|
xfree(stack);
|
94
79
|
}
|
95
80
|
|
@@ -193,7 +178,8 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
|
|
193
178
|
|
194
179
|
if(proc != Qnil) {
|
195
180
|
VALUE obj;
|
196
|
-
|
181
|
+
VALUE arg = (str == Qnil ? rb_str_buf_new(0) : str);
|
182
|
+
obj = rb_proc_call_with_block(proc, 1, &arg, Qnil);
|
197
183
|
return object_complete(uk, obj);
|
198
184
|
}
|
199
185
|
|
@@ -323,7 +309,7 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
|
|
323
309
|
child_stack->parent = uk->stack;
|
324
310
|
uk->stack = child_stack;
|
325
311
|
|
326
|
-
obj =
|
312
|
+
obj = rb_proc_call_with_block(proc, 1, &uk->self, Qnil);
|
327
313
|
|
328
314
|
uk->stack = child_stack->parent;
|
329
315
|
_msgpack_unpacker_free_stack(child_stack);
|