msgpack 1.6.0 → 1.7.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 +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
|
}
|