msgpack 1.6.0 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog +14 -0
- data/README.md +27 -0
- data/ext/java/org/msgpack/jruby/ExtensionRegistry.java +4 -9
- data/ext/java/org/msgpack/jruby/Factory.java +1 -1
- data/ext/java/org/msgpack/jruby/Packer.java +3 -0
- data/ext/java/org/msgpack/jruby/Unpacker.java +3 -0
- data/ext/msgpack/buffer.c +9 -12
- data/ext/msgpack/buffer.h +2 -10
- data/ext/msgpack/buffer_class.c +4 -4
- data/ext/msgpack/extconf.rb +3 -15
- data/ext/msgpack/factory_class.c +1 -1
- data/ext/msgpack/packer.c +1 -0
- data/ext/msgpack/packer_class.c +9 -19
- data/ext/msgpack/rbinit.c +1 -1
- data/ext/msgpack/rmem.c +3 -4
- data/ext/msgpack/unpacker.c +8 -20
- data/ext/msgpack/unpacker.h +0 -4
- data/ext/msgpack/unpacker_class.c +11 -21
- data/lib/msgpack/buffer.rb +9 -0
- data/lib/msgpack/factory.rb +41 -53
- data/lib/msgpack/packer.rb +4 -0
- data/lib/msgpack/unpacker.rb +4 -0
- data/lib/msgpack/version.rb +1 -1
- data/lib/msgpack.rb +1 -0
- data/msgpack.gemspec +6 -3
- metadata +19 -48
- data/.github/workflows/ci.yaml +0 -57
- data/.gitignore +0 -23
- data/.rubocop.yml +0 -36
- data/Gemfile +0 -9
- data/Rakefile +0 -70
- data/appveyor.yml +0 -18
- data/bench/bench.rb +0 -78
- data/bin/console +0 -8
- data/doclib/msgpack/buffer.rb +0 -193
- data/doclib/msgpack/core_ext.rb +0 -101
- data/doclib/msgpack/error.rb +0 -19
- data/doclib/msgpack/extension_value.rb +0 -9
- data/doclib/msgpack/factory.rb +0 -145
- data/doclib/msgpack/packer.rb +0 -209
- data/doclib/msgpack/time.rb +0 -22
- data/doclib/msgpack/timestamp.rb +0 -44
- data/doclib/msgpack/unpacker.rb +0 -183
- data/doclib/msgpack.rb +0 -87
- data/msgpack.org.md +0 -46
- data/spec/bigint_spec.rb +0 -26
- data/spec/cases.json +0 -1
- data/spec/cases.msg +0 -0
- data/spec/cases_compact.msg +0 -0
- data/spec/cases_spec.rb +0 -39
- data/spec/cruby/buffer_io_spec.rb +0 -255
- data/spec/cruby/buffer_packer.rb +0 -29
- data/spec/cruby/buffer_spec.rb +0 -592
- data/spec/cruby/buffer_unpacker.rb +0 -19
- data/spec/cruby/unpacker_spec.rb +0 -70
- data/spec/ext_value_spec.rb +0 -99
- data/spec/exttypes.rb +0 -51
- data/spec/factory_spec.rb +0 -706
- data/spec/format_spec.rb +0 -301
- data/spec/jruby/benchmarks/shootout_bm.rb +0 -73
- data/spec/jruby/benchmarks/symbolize_keys_bm.rb +0 -25
- data/spec/jruby/unpacker_spec.rb +0 -186
- data/spec/msgpack_spec.rb +0 -214
- data/spec/pack_spec.rb +0 -61
- data/spec/packer_spec.rb +0 -575
- data/spec/random_compat.rb +0 -24
- data/spec/spec_helper.rb +0 -72
- data/spec/timestamp_spec.rb +0 -159
- data/spec/unpack_spec.rb +0 -57
- data/spec/unpacker_spec.rb +0 -869
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1414cbfba4f8503d851d6084ef42eb39cfe652d0cadedcf75523e5f472bf425b
|
4
|
+
data.tar.gz: a863d42ac8880a77afe84398b103f4b27d0782db70dd31aad4c785759bcfa20f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9ffd9d63c8354684cedfcd682beaf525823646aa9b0b6854175e81f1879eea22fcbf3fba560744210129001263ff80b2fc83ebc99a7405d9f03570921567b1d7
|
7
|
+
data.tar.gz: 4bd0b851caa3d39c05e32d6d90f9f52c376aae4f799247d3d9569db9bc273171c85973e6229de6b9c55e956e2f8c9790a9a4c23e8482944233ed499b421f30c6
|
data/ChangeLog
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
2023-03-29 1.7.0:
|
2
|
+
|
3
|
+
* Fix a possible double-free issue when GC triggers inside `_msgpack_rmem_alloc2`.
|
4
|
+
* `Unpacker#feed` now always directly read in provided strings instead of copying content in its buffer.
|
5
|
+
* `Unpacker#feed` is now an alias of `Unpacker#feed_reference`.
|
6
|
+
* Implement `Factory::Pool#unpacker` and `Factory::Pool#packer` to allow for more precise serialization.
|
7
|
+
* Require Ruby 2.5+.
|
8
|
+
|
9
|
+
2023-03-03 1.6.1:
|
10
|
+
|
11
|
+
* Undefine `#clone` and `#dup` on `MessagePack::Buffer`, `MessagePack::Packer` and `MessagePack::Unpacker`.
|
12
|
+
These methods were never intended, and using them could cause leaks or crashes or worse.
|
13
|
+
* Fix a possible GC crash when GC trigger inside `MessagePack::Buffer.new` (#314).
|
14
|
+
|
1
15
|
2022-09-30 1.6.0:
|
2
16
|
|
3
17
|
* Fix a potential use-after-free bug in Buffer_free when accessing a packer or unpacker buffer.
|
data/README.md
CHANGED
@@ -211,6 +211,33 @@ factory.register_type(
|
|
211
211
|
factory.load(factory.dump(Point.new(12, 34))) # => #<struct Point x=12, y=34>
|
212
212
|
```
|
213
213
|
|
214
|
+
## Pooling
|
215
|
+
|
216
|
+
Creating `Packer` and `Unpacker` objects is expensive. For best performance it is preferable to re-use these objects.
|
217
|
+
|
218
|
+
`MessagePack::Factory#pool` makes that easier:
|
219
|
+
|
220
|
+
```ruby
|
221
|
+
factory = MessagePack::Factory.new
|
222
|
+
factory.register_type(
|
223
|
+
0x01,
|
224
|
+
Point,
|
225
|
+
packer: ->(point, packer) {
|
226
|
+
packer.write(point.x)
|
227
|
+
packer.write(point.y)
|
228
|
+
},
|
229
|
+
unpacker: ->(unpacker) {
|
230
|
+
x = unpacker.read
|
231
|
+
y = unpacker.read
|
232
|
+
Point.new(x, y)
|
233
|
+
},
|
234
|
+
recursive: true,
|
235
|
+
)
|
236
|
+
pool = factory.pool(5) # The pool size should match the number of threads expected to use the factory concurrently.
|
237
|
+
|
238
|
+
pool.load(pool.dump(Point.new(12, 34))) # => #<struct Point x=12, y=34>
|
239
|
+
```
|
240
|
+
|
214
241
|
## Buffer API
|
215
242
|
|
216
243
|
MessagePack for Ruby provides a buffer API so that you can read or write data by hand, not via Packer or Unpacker API.
|
@@ -18,22 +18,17 @@ public class ExtensionRegistry {
|
|
18
18
|
private final ExtensionEntry[] extensionsByTypeId;
|
19
19
|
|
20
20
|
public ExtensionRegistry() {
|
21
|
-
this(new HashMap<RubyModule, ExtensionEntry>());
|
21
|
+
this(new HashMap<RubyModule, ExtensionEntry>(), new ExtensionEntry[256]);
|
22
22
|
}
|
23
23
|
|
24
|
-
private ExtensionRegistry(Map<RubyModule, ExtensionEntry> extensionsByModule) {
|
24
|
+
private ExtensionRegistry(Map<RubyModule, ExtensionEntry> extensionsByModule, ExtensionEntry[] extensionsByTypeId) {
|
25
25
|
this.extensionsByModule = new HashMap<RubyModule, ExtensionEntry>(extensionsByModule);
|
26
26
|
this.extensionsByAncestor = new HashMap<RubyModule, ExtensionEntry>();
|
27
|
-
this.extensionsByTypeId =
|
28
|
-
for (ExtensionEntry entry : extensionsByModule.values()) {
|
29
|
-
if (entry.hasUnpacker()) {
|
30
|
-
extensionsByTypeId[entry.getTypeId() + 128] = entry;
|
31
|
-
}
|
32
|
-
}
|
27
|
+
this.extensionsByTypeId = extensionsByTypeId.clone();
|
33
28
|
}
|
34
29
|
|
35
30
|
public ExtensionRegistry dup() {
|
36
|
-
return new ExtensionRegistry(extensionsByModule);
|
31
|
+
return new ExtensionRegistry(extensionsByModule, extensionsByTypeId);
|
37
32
|
}
|
38
33
|
|
39
34
|
public IRubyObject toInternalPackerRegistry(ThreadContext ctx) {
|
@@ -96,6 +96,9 @@ public class Packer extends RubyObject {
|
|
96
96
|
@JRubyMethod(name = "register_type", required = 2, optional = 1)
|
97
97
|
public IRubyObject registerType(ThreadContext ctx, IRubyObject[] args, final Block block) {
|
98
98
|
Ruby runtime = ctx.runtime;
|
99
|
+
if (isFrozen()) {
|
100
|
+
throw runtime.newFrozenError("MessagePack::Packer");
|
101
|
+
}
|
99
102
|
IRubyObject type = args[0];
|
100
103
|
IRubyObject mod = args[1];
|
101
104
|
|
@@ -130,6 +130,9 @@ public class Unpacker extends RubyObject {
|
|
130
130
|
@JRubyMethod(name = "register_type", required = 1, optional = 2)
|
131
131
|
public IRubyObject registerType(ThreadContext ctx, IRubyObject[] args, final Block block) {
|
132
132
|
Ruby runtime = ctx.runtime;
|
133
|
+
if (isFrozen()) {
|
134
|
+
throw runtime.newFrozenError("MessagePack::Unpacker");
|
135
|
+
}
|
133
136
|
IRubyObject type = args[0];
|
134
137
|
|
135
138
|
RubyModule extModule;
|
data/ext/msgpack/buffer.c
CHANGED
@@ -19,10 +19,6 @@
|
|
19
19
|
#include "buffer.h"
|
20
20
|
#include "rmem.h"
|
21
21
|
|
22
|
-
#ifndef HAVE_RB_STR_REPLACE
|
23
|
-
static ID s_replace;
|
24
|
-
#endif
|
25
|
-
|
26
22
|
int msgpack_rb_encindex_utf8;
|
27
23
|
int msgpack_rb_encindex_usascii;
|
28
24
|
int msgpack_rb_encindex_ascii8bit;
|
@@ -40,10 +36,6 @@ void msgpack_buffer_static_init(void)
|
|
40
36
|
msgpack_rb_encindex_ascii8bit = rb_ascii8bit_encindex();
|
41
37
|
|
42
38
|
msgpack_rmem_init(&s_rmem);
|
43
|
-
|
44
|
-
#ifndef HAVE_RB_STR_REPLACE
|
45
|
-
s_replace = rb_intern("replace");
|
46
|
-
#endif
|
47
39
|
}
|
48
40
|
|
49
41
|
void msgpack_buffer_static_destroy(void)
|
@@ -66,7 +58,11 @@ void msgpack_buffer_init(msgpack_buffer_t* b)
|
|
66
58
|
static void _msgpack_buffer_chunk_destroy(msgpack_buffer_chunk_t* c)
|
67
59
|
{
|
68
60
|
if(c->mem != NULL) {
|
69
|
-
if(
|
61
|
+
if(c->rmem) {
|
62
|
+
if(!msgpack_rmem_free(&s_rmem, c->mem)) {
|
63
|
+
rb_bug("Failed to free an rmem pointer, memory leak?");
|
64
|
+
}
|
65
|
+
} else {
|
70
66
|
xfree(c->mem);
|
71
67
|
}
|
72
68
|
/* no needs to update rmem_owner because chunks will not be
|
@@ -330,14 +326,12 @@ static inline void _msgpack_buffer_append_reference(msgpack_buffer_t* b, VALUE s
|
|
330
326
|
|
331
327
|
void _msgpack_buffer_append_long_string(msgpack_buffer_t* b, VALUE string)
|
332
328
|
{
|
333
|
-
size_t length = RSTRING_LEN(string);
|
334
|
-
|
335
329
|
if(b->io != Qnil) {
|
336
330
|
msgpack_buffer_flush(b);
|
337
331
|
if (ENCODING_GET(string) == msgpack_rb_encindex_ascii8bit) {
|
338
332
|
rb_funcall(b->io, b->io_write_all_method, 1, string);
|
339
333
|
} else {
|
340
|
-
msgpack_buffer_append(b, RSTRING_PTR(string),
|
334
|
+
msgpack_buffer_append(b, RSTRING_PTR(string), RSTRING_LEN(string));
|
341
335
|
}
|
342
336
|
} else {
|
343
337
|
_msgpack_buffer_append_reference(b, string);
|
@@ -349,6 +343,8 @@ static inline void* _msgpack_buffer_chunk_malloc(
|
|
349
343
|
size_t required_size, size_t* allocated_size)
|
350
344
|
{
|
351
345
|
if(required_size <= MSGPACK_RMEM_PAGE_SIZE) {
|
346
|
+
c->rmem = true;
|
347
|
+
|
352
348
|
if((size_t)(b->rmem_end - b->rmem_last) < required_size) {
|
353
349
|
/* alloc new rmem page */
|
354
350
|
*allocated_size = MSGPACK_RMEM_PAGE_SIZE;
|
@@ -379,6 +375,7 @@ static inline void* _msgpack_buffer_chunk_malloc(
|
|
379
375
|
*allocated_size = required_size;
|
380
376
|
void* mem = xmalloc(required_size);
|
381
377
|
c->mem = mem;
|
378
|
+
c->rmem = false;
|
382
379
|
return mem;
|
383
380
|
}
|
384
381
|
|
data/ext/msgpack/buffer.h
CHANGED
@@ -78,6 +78,7 @@ struct msgpack_buffer_chunk_t {
|
|
78
78
|
void* mem;
|
79
79
|
msgpack_buffer_chunk_t* next;
|
80
80
|
VALUE mapped_string; /* RBString or NO_MAPPED_STRING */
|
81
|
+
bool rmem;
|
81
82
|
};
|
82
83
|
|
83
84
|
union msgpack_buffer_cast_block_t {
|
@@ -267,14 +268,7 @@ static inline size_t msgpack_buffer_append_string(msgpack_buffer_t* b, VALUE str
|
|
267
268
|
static inline size_t msgpack_buffer_append_string_reference(msgpack_buffer_t* b, VALUE string)
|
268
269
|
{
|
269
270
|
size_t length = RSTRING_LEN(string);
|
270
|
-
|
271
|
-
if(length > MSGPACK_BUFFER_STRING_WRITE_REFERENCE_MINIMUM) {
|
272
|
-
_msgpack_buffer_append_long_string(b, string);
|
273
|
-
|
274
|
-
} else {
|
275
|
-
msgpack_buffer_append(b, RSTRING_PTR(string), length);
|
276
|
-
}
|
277
|
-
|
271
|
+
_msgpack_buffer_append_long_string(b, string);
|
278
272
|
return length;
|
279
273
|
}
|
280
274
|
|
@@ -479,7 +473,6 @@ static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_
|
|
479
473
|
result = rb_str_new(b->read_buffer, length);
|
480
474
|
}
|
481
475
|
|
482
|
-
#if STR_UMINUS_DEDUPE
|
483
476
|
if (will_be_frozen) {
|
484
477
|
#if STR_UMINUS_DEDUPE_FROZEN
|
485
478
|
// Starting from MRI 2.8 it is preferable to freeze the string
|
@@ -491,7 +484,6 @@ static inline VALUE msgpack_buffer_read_top_as_string(msgpack_buffer_t* b, size_
|
|
491
484
|
// frozen.
|
492
485
|
result = rb_funcall(result, s_uminus, 0);
|
493
486
|
}
|
494
|
-
#endif // STR_UMINUS_DEDUPE
|
495
487
|
_msgpack_buffer_consumed(b, length);
|
496
488
|
return result;
|
497
489
|
|
data/ext/msgpack/buffer_class.c
CHANGED
@@ -56,7 +56,7 @@ static size_t Buffer_memsize(const void *data)
|
|
56
56
|
return sizeof(msgpack_buffer_t) + msgpack_buffer_memsize(data);
|
57
57
|
}
|
58
58
|
|
59
|
-
const rb_data_type_t buffer_data_type = {
|
59
|
+
static const rb_data_type_t buffer_data_type = {
|
60
60
|
.wrap_struct_name = "msgpack:buffer",
|
61
61
|
.function = {
|
62
62
|
.dmark = msgpack_buffer_mark,
|
@@ -66,10 +66,10 @@ const rb_data_type_t buffer_data_type = {
|
|
66
66
|
.flags = RUBY_TYPED_FREE_IMMEDIATELY
|
67
67
|
};
|
68
68
|
|
69
|
-
const rb_data_type_t buffer_view_data_type = {
|
69
|
+
static const rb_data_type_t buffer_view_data_type = {
|
70
70
|
.wrap_struct_name = "msgpack:buffer_view",
|
71
71
|
.function = {
|
72
|
-
.dmark =
|
72
|
+
.dmark = NULL,
|
73
73
|
.dfree = NULL,
|
74
74
|
.dsize = NULL,
|
75
75
|
},
|
@@ -91,8 +91,8 @@ static VALUE Buffer_alloc(VALUE klass)
|
|
91
91
|
{
|
92
92
|
msgpack_buffer_t* b;
|
93
93
|
VALUE buffer = TypedData_Make_Struct(klass, msgpack_buffer_t, &buffer_data_type, b);
|
94
|
-
rb_ivar_set(buffer, s_at_owner, Qnil);
|
95
94
|
msgpack_buffer_init(b);
|
95
|
+
rb_ivar_set(buffer, s_at_owner, Qnil);
|
96
96
|
return buffer;
|
97
97
|
}
|
98
98
|
|
data/ext/msgpack/extconf.rb
CHANGED
@@ -5,11 +5,13 @@ have_header("st.h")
|
|
5
5
|
have_func("rb_enc_interned_str", "ruby.h") # Ruby 3.0+
|
6
6
|
have_func("rb_hash_new_capa", "ruby.h") # Ruby 3.2+
|
7
7
|
|
8
|
+
$CFLAGS << " -fvisibility=hidden "
|
9
|
+
|
8
10
|
unless RUBY_PLATFORM.include? 'mswin'
|
9
11
|
$CFLAGS << %[ -I.. -Wall -O3 #{RbConfig::CONFIG["debugflags"]} -std=gnu99]
|
10
12
|
end
|
11
13
|
|
12
|
-
if RUBY_VERSION.start_with?('3.0.')
|
14
|
+
if RUBY_VERSION.start_with?('3.0.') && RUBY_VERSION <= '3.0.5'
|
13
15
|
# https://bugs.ruby-lang.org/issues/18772
|
14
16
|
$CFLAGS << ' -DRB_ENC_INTERNED_STR_NULL_CHECK=1 '
|
15
17
|
end
|
@@ -26,20 +28,6 @@ else
|
|
26
28
|
$CFLAGS << ' -DHASH_ASET_DEDUPE=0 '
|
27
29
|
end
|
28
30
|
|
29
|
-
|
30
|
-
# checking if String#-@ (str_uminus) dedupes... ' (Ruby 2.5+)
|
31
|
-
begin
|
32
|
-
a = -(%w(t e s t).join)
|
33
|
-
b = -(%w(t e s t).join)
|
34
|
-
if a.equal?(b)
|
35
|
-
$CFLAGS << ' -DSTR_UMINUS_DEDUPE=1 '
|
36
|
-
else
|
37
|
-
$CFLAGS += ' -DSTR_UMINUS_DEDUPE=0 '
|
38
|
-
end
|
39
|
-
rescue NoMethodError
|
40
|
-
$CFLAGS << ' -DSTR_UMINUS_DEDUPE=0 '
|
41
|
-
end
|
42
|
-
|
43
31
|
# checking if String#-@ (str_uminus) directly interns frozen strings... ' (Ruby 3.0+)
|
44
32
|
begin
|
45
33
|
s = rand.to_s.freeze
|
data/ext/msgpack/factory_class.c
CHANGED
@@ -212,7 +212,7 @@ static VALUE Factory_register_type(int argc, VALUE* argv, VALUE self)
|
|
212
212
|
VALUE packer_proc, unpacker_proc;
|
213
213
|
|
214
214
|
if (OBJ_FROZEN(self)) {
|
215
|
-
rb_raise(
|
215
|
+
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Factory");
|
216
216
|
}
|
217
217
|
|
218
218
|
switch (argc) {
|
data/ext/msgpack/packer.c
CHANGED
data/ext/msgpack/packer_class.c
CHANGED
@@ -47,6 +47,7 @@ static void Packer_free(void *ptr)
|
|
47
47
|
static void Packer_mark(void *ptr)
|
48
48
|
{
|
49
49
|
msgpack_packer_t* pk = ptr;
|
50
|
+
msgpack_buffer_mark(pk);
|
50
51
|
msgpack_packer_mark(pk);
|
51
52
|
msgpack_packer_ext_registry_mark(&pk->ext_registry);
|
52
53
|
}
|
@@ -106,7 +107,7 @@ VALUE MessagePack_Packer_initialize(int argc, VALUE* argv, VALUE self)
|
|
106
107
|
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
107
108
|
|
108
109
|
msgpack_packer_ext_registry_init(&pk->ext_registry);
|
109
|
-
pk->buffer_ref =
|
110
|
+
pk->buffer_ref = Qnil;
|
110
111
|
|
111
112
|
MessagePack_Buffer_set_options(PACKER_BUFFER_(pk), io, options);
|
112
113
|
|
@@ -129,6 +130,9 @@ static VALUE Packer_compatibility_mode_p(VALUE self)
|
|
129
130
|
static VALUE Packer_buffer(VALUE self)
|
130
131
|
{
|
131
132
|
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
133
|
+
if (!RTEST(pk->buffer_ref)) {
|
134
|
+
pk->buffer_ref = MessagePack_Buffer_wrap(PACKER_BUFFER_(pk), self);
|
135
|
+
}
|
132
136
|
return pk->buffer_ref;
|
133
137
|
}
|
134
138
|
|
@@ -334,18 +338,6 @@ static VALUE Packer_write_to(VALUE self, VALUE io)
|
|
334
338
|
return SIZET2NUM(sz);
|
335
339
|
}
|
336
340
|
|
337
|
-
//static VALUE Packer_append(VALUE self, VALUE string_or_buffer)
|
338
|
-
//{
|
339
|
-
// msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
340
|
-
//
|
341
|
-
// // TODO if string_or_buffer is a Buffer
|
342
|
-
// VALUE string = string_or_buffer;
|
343
|
-
//
|
344
|
-
// msgpack_buffer_append_string(PACKER_BUFFER_(pk), string);
|
345
|
-
//
|
346
|
-
// return self;
|
347
|
-
//}
|
348
|
-
|
349
341
|
static VALUE Packer_registered_types_internal(VALUE self)
|
350
342
|
{
|
351
343
|
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
@@ -357,6 +349,10 @@ static VALUE Packer_registered_types_internal(VALUE self)
|
|
357
349
|
|
358
350
|
static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
|
359
351
|
{
|
352
|
+
if (OBJ_FROZEN(self)) {
|
353
|
+
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Packer");
|
354
|
+
}
|
355
|
+
|
360
356
|
msgpack_packer_t *pk = MessagePack_Packer_get(self);
|
361
357
|
|
362
358
|
int ext_type;
|
@@ -463,15 +459,9 @@ void MessagePack_Packer_module_init(VALUE mMessagePack)
|
|
463
459
|
rb_define_method(cMessagePack_Packer, "to_str", Packer_to_str, 0);
|
464
460
|
rb_define_alias(cMessagePack_Packer, "to_s", "to_str");
|
465
461
|
rb_define_method(cMessagePack_Packer, "to_a", Packer_to_a, 0);
|
466
|
-
//rb_define_method(cMessagePack_Packer, "append", Packer_append, 1);
|
467
|
-
//rb_define_alias(cMessagePack_Packer, "<<", "append");
|
468
462
|
|
469
463
|
rb_define_private_method(cMessagePack_Packer, "registered_types_internal", Packer_registered_types_internal, 0);
|
470
464
|
rb_define_method(cMessagePack_Packer, "register_type", Packer_register_type, -1);
|
471
465
|
|
472
|
-
//s_packer_value = MessagePack_Packer_alloc(cMessagePack_Packer);
|
473
|
-
//rb_gc_register_address(&s_packer_value);
|
474
|
-
//Data_Get_Struct(s_packer_value, msgpack_packer_t, s_packer);
|
475
|
-
|
476
466
|
rb_define_method(cMessagePack_Packer, "full_pack", Packer_full_pack, 0);
|
477
467
|
}
|
data/ext/msgpack/rbinit.c
CHANGED
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
@@ -20,19 +20,17 @@
|
|
20
20
|
#include "rmem.h"
|
21
21
|
#include "extension_value_class.h"
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
|
+
);
|
27
27
|
|
28
28
|
static int RAW_TYPE_STRING = 256;
|
29
29
|
static int RAW_TYPE_BINARY = 257;
|
30
30
|
|
31
31
|
static ID s_call;
|
32
32
|
|
33
|
-
#ifdef UNPACKER_STACK_RMEM
|
34
33
|
static msgpack_rmem_t s_stack_rmem;
|
35
|
-
#endif
|
36
34
|
|
37
35
|
#if !defined(HAVE_RB_HASH_NEW_CAPA)
|
38
36
|
static inline VALUE rb_hash_new_capa(long capa)
|
@@ -43,18 +41,14 @@ static inline VALUE rb_hash_new_capa(long capa)
|
|
43
41
|
|
44
42
|
void msgpack_unpacker_static_init(void)
|
45
43
|
{
|
46
|
-
#ifdef UNPACKER_STACK_RMEM
|
47
44
|
msgpack_rmem_init(&s_stack_rmem);
|
48
|
-
#endif
|
49
45
|
|
50
46
|
s_call = rb_intern("call");
|
51
47
|
}
|
52
48
|
|
53
49
|
void msgpack_unpacker_static_destroy(void)
|
54
50
|
{
|
55
|
-
#ifdef UNPACKER_STACK_RMEM
|
56
51
|
msgpack_rmem_destroy(&s_stack_rmem);
|
57
|
-
#endif
|
58
52
|
}
|
59
53
|
|
60
54
|
#define HEAD_BYTE_REQUIRED 0xc1
|
@@ -62,13 +56,8 @@ void msgpack_unpacker_static_destroy(void)
|
|
62
56
|
static inline msgpack_unpacker_stack_t* _msgpack_unpacker_new_stack(void) {
|
63
57
|
msgpack_unpacker_stack_t *stack = ZALLOC(msgpack_unpacker_stack_t);
|
64
58
|
stack->capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
|
65
|
-
#ifdef UNPACKER_STACK_RMEM
|
66
59
|
stack->data = msgpack_rmem_alloc(&s_stack_rmem);
|
67
60
|
/*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
61
|
return stack;
|
73
62
|
}
|
74
63
|
|
@@ -85,11 +74,9 @@ void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
|
|
85
74
|
}
|
86
75
|
|
87
76
|
static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
xfree(stack->data);
|
92
|
-
#endif
|
77
|
+
if (!msgpack_rmem_free(&s_stack_rmem, stack->data)) {
|
78
|
+
rb_bug("Failed to free an rmem pointer, memory leak?");
|
79
|
+
}
|
93
80
|
xfree(stack);
|
94
81
|
}
|
95
82
|
|
@@ -120,6 +107,7 @@ void msgpack_unpacker_mark(msgpack_unpacker_t* uk)
|
|
120
107
|
/* See MessagePack_Buffer_wrap */
|
121
108
|
/* msgpack_buffer_mark(UNPACKER_BUFFER_(uk)); */
|
122
109
|
rb_gc_mark(uk->buffer_ref);
|
110
|
+
rb_gc_mark(uk->self);
|
123
111
|
}
|
124
112
|
|
125
113
|
void _msgpack_unpacker_reset(msgpack_unpacker_t* uk)
|
data/ext/msgpack/unpacker.h
CHANGED
@@ -21,9 +21,7 @@
|
|
21
21
|
#include "buffer.h"
|
22
22
|
#include "unpacker_ext_registry.h"
|
23
23
|
|
24
|
-
#ifndef MSGPACK_UNPACKER_STACK_CAPACITY
|
25
24
|
#define MSGPACK_UNPACKER_STACK_CAPACITY 128
|
26
|
-
#endif
|
27
25
|
|
28
26
|
struct msgpack_unpacker_t;
|
29
27
|
typedef struct msgpack_unpacker_t msgpack_unpacker_t;
|
@@ -49,8 +47,6 @@ struct msgpack_unpacker_stack_t {
|
|
49
47
|
msgpack_unpacker_stack_t *parent;
|
50
48
|
};
|
51
49
|
|
52
|
-
#define MSGPACK_UNPACKER_STACK_SIZE (8+4+8+8) /* assumes size_t <= 64bit, enum <= 32bit, VALUE <= 64bit */
|
53
|
-
|
54
50
|
struct msgpack_unpacker_t {
|
55
51
|
msgpack_buffer_t buffer;
|
56
52
|
msgpack_unpacker_stack_t *stack;
|
@@ -51,6 +51,7 @@ static void Unpacker_free(void *ptr)
|
|
51
51
|
static void Unpacker_mark(void *ptr)
|
52
52
|
{
|
53
53
|
msgpack_unpacker_t* uk = ptr;
|
54
|
+
msgpack_buffer_mark(uk);
|
54
55
|
msgpack_unpacker_mark(uk);
|
55
56
|
msgpack_unpacker_ext_registry_mark(uk->ext_registry);
|
56
57
|
}
|
@@ -117,7 +118,7 @@ VALUE MessagePack_Unpacker_initialize(int argc, VALUE* argv, VALUE self)
|
|
117
118
|
|
118
119
|
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
119
120
|
|
120
|
-
uk->buffer_ref =
|
121
|
+
uk->buffer_ref = Qnil;
|
121
122
|
|
122
123
|
MessagePack_Buffer_set_options(UNPACKER_BUFFER_(uk), io, options);
|
123
124
|
|
@@ -177,6 +178,9 @@ NORETURN(static void raise_unpacker_error(int r))
|
|
177
178
|
static VALUE Unpacker_buffer(VALUE self)
|
178
179
|
{
|
179
180
|
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
181
|
+
if (!RTEST(uk->buffer_ref)) {
|
182
|
+
uk->buffer_ref = MessagePack_Buffer_wrap(UNPACKER_BUFFER_(uk), self);
|
183
|
+
}
|
180
184
|
return uk->buffer_ref;
|
181
185
|
}
|
182
186
|
|
@@ -245,18 +249,6 @@ static VALUE Unpacker_read_map_header(VALUE self)
|
|
245
249
|
return ULONG2NUM(size); // long at least 32 bits
|
246
250
|
}
|
247
251
|
|
248
|
-
|
249
|
-
static VALUE Unpacker_feed(VALUE self, VALUE data)
|
250
|
-
{
|
251
|
-
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
252
|
-
|
253
|
-
StringValue(data);
|
254
|
-
|
255
|
-
msgpack_buffer_append_string(UNPACKER_BUFFER_(uk), data);
|
256
|
-
|
257
|
-
return self;
|
258
|
-
}
|
259
|
-
|
260
252
|
static VALUE Unpacker_feed_reference(VALUE self, VALUE data)
|
261
253
|
{
|
262
254
|
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
@@ -356,6 +348,10 @@ static VALUE Unpacker_registered_types_internal(VALUE self)
|
|
356
348
|
|
357
349
|
static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
|
358
350
|
{
|
351
|
+
if (OBJ_FROZEN(self)) {
|
352
|
+
rb_raise(rb_eFrozenError, "can't modify frozen MessagePack::Unpacker");
|
353
|
+
}
|
354
|
+
|
359
355
|
msgpack_unpacker_t *uk = MessagePack_Unpacker_get(self);
|
360
356
|
|
361
357
|
int ext_type;
|
@@ -453,8 +449,8 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
453
449
|
rb_define_method(cMessagePack_Unpacker, "skip_nil", Unpacker_skip_nil, 0);
|
454
450
|
rb_define_method(cMessagePack_Unpacker, "read_array_header", Unpacker_read_array_header, 0);
|
455
451
|
rb_define_method(cMessagePack_Unpacker, "read_map_header", Unpacker_read_map_header, 0);
|
456
|
-
rb_define_method(cMessagePack_Unpacker, "feed",
|
457
|
-
|
452
|
+
rb_define_method(cMessagePack_Unpacker, "feed", Unpacker_feed_reference, 1);
|
453
|
+
rb_define_alias(cMessagePack_Unpacker, "feed_reference", "feed");
|
458
454
|
rb_define_method(cMessagePack_Unpacker, "each", Unpacker_each, 0);
|
459
455
|
rb_define_method(cMessagePack_Unpacker, "feed_each", Unpacker_feed_each, 1);
|
460
456
|
rb_define_method(cMessagePack_Unpacker, "reset", Unpacker_reset, 0);
|
@@ -462,11 +458,5 @@ void MessagePack_Unpacker_module_init(VALUE mMessagePack)
|
|
462
458
|
rb_define_private_method(cMessagePack_Unpacker, "registered_types_internal", Unpacker_registered_types_internal, 0);
|
463
459
|
rb_define_method(cMessagePack_Unpacker, "register_type", Unpacker_register_type, -1);
|
464
460
|
|
465
|
-
//s_unpacker_value = MessagePack_Unpacker_alloc(cMessagePack_Unpacker);
|
466
|
-
//rb_gc_register_address(&s_unpacker_value);
|
467
|
-
//Data_Get_Struct(s_unpacker_value, msgpack_unpacker_t, s_unpacker);
|
468
|
-
/* prefer reference than copying */
|
469
|
-
//msgpack_buffer_set_write_reference_threshold(UNPACKER_BUFFER_(s_unpacker), 0);
|
470
|
-
|
471
461
|
rb_define_method(cMessagePack_Unpacker, "full_unpack", Unpacker_full_unpack, 0);
|
472
462
|
}
|