msgpack 1.7.2 → 1.8.3

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.
@@ -20,23 +20,65 @@
20
20
  #include "rmem.h"
21
21
  #include "extension_value_class.h"
22
22
  #include <assert.h>
23
+ #include <limits.h>
23
24
 
24
25
  #if !defined(HAVE_RB_PROC_CALL_WITH_BLOCK)
25
26
  #define rb_proc_call_with_block(recv, argc, argv, block) rb_funcallv(recv, rb_intern("call"), argc, argv)
26
27
  #endif
27
28
 
29
+ #ifndef HAVE_RB_GC_MARK_LOCATIONS
30
+ // For TruffleRuby
31
+ void rb_gc_mark_locations(const VALUE *start, const VALUE *end)
32
+ {
33
+ VALUE *value = start;
34
+
35
+ while (value < end) {
36
+ rb_gc_mark(*value);
37
+ value++;
38
+ }
39
+ }
40
+ #endif
41
+
42
+ struct protected_proc_call_args {
43
+ VALUE proc;
44
+ int argc;
45
+ VALUE *argv;
46
+ };
47
+
48
+ static VALUE protected_proc_call_safe(VALUE _args) {
49
+ struct protected_proc_call_args *args = (struct protected_proc_call_args *)_args;
50
+
51
+ return rb_proc_call_with_block(args->proc, args->argc, args->argv, Qnil);
52
+ }
53
+
54
+ static VALUE protected_proc_call(VALUE proc, int argc, VALUE *argv, int *raised) {
55
+ struct protected_proc_call_args args = {
56
+ .proc = proc,
57
+ .argc = argc,
58
+ .argv = argv,
59
+ };
60
+ return rb_protect(protected_proc_call_safe, (VALUE)&args, raised);
61
+ }
62
+
28
63
  static int RAW_TYPE_STRING = 256;
29
64
  static int RAW_TYPE_BINARY = 257;
65
+ static int16_t INITIAL_BUFFER_CAPACITY_MAX = SHRT_MAX;
30
66
 
31
67
  static msgpack_rmem_t s_stack_rmem;
32
68
 
33
69
  #if !defined(HAVE_RB_HASH_NEW_CAPA)
34
- static inline VALUE rb_hash_new_capa(long capa)
70
+ static inline VALUE rb_hash_new_capa_inline(long capa)
35
71
  {
36
72
  return rb_hash_new();
37
73
  }
74
+ #define rb_hash_new_capa rb_hash_new_capa_inline
38
75
  #endif
39
76
 
77
+ static inline int16_t initial_buffer_size(long size)
78
+ {
79
+ return (size > INITIAL_BUFFER_CAPACITY_MAX) ? INITIAL_BUFFER_CAPACITY_MAX : size;
80
+ }
81
+
40
82
  void msgpack_unpacker_static_init(void)
41
83
  {
42
84
  assert(sizeof(msgpack_unpacker_stack_entry_t) * MSGPACK_UNPACKER_STACK_CAPACITY <= MSGPACK_RMEM_PAGE_SIZE);
@@ -51,14 +93,29 @@ void msgpack_unpacker_static_destroy(void)
51
93
 
52
94
  #define HEAD_BYTE_REQUIRED 0xc1
53
95
 
54
- static inline msgpack_unpacker_stack_t* _msgpack_unpacker_new_stack(void) {
55
- msgpack_unpacker_stack_t *stack = ZALLOC(msgpack_unpacker_stack_t);
56
- stack->capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
57
- stack->data = msgpack_rmem_alloc(&s_stack_rmem);
58
- /*memset(uk->stack, 0, MSGPACK_UNPACKER_STACK_CAPACITY);*/
59
- return stack;
96
+ static inline bool _msgpack_unpacker_stack_init(msgpack_unpacker_stack_t *stack) {
97
+ if (!stack->data) {
98
+ stack->capacity = MSGPACK_UNPACKER_STACK_CAPACITY;
99
+ stack->data = msgpack_rmem_alloc(&s_stack_rmem);
100
+ stack->depth = 0;
101
+ return true;
102
+ }
103
+ return false;
104
+ }
105
+
106
+ static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
107
+ if (stack->data) {
108
+ if (!msgpack_rmem_free(&s_stack_rmem, stack->data)) {
109
+ rb_bug("Failed to free an rmem pointer, memory leak?");
110
+ }
111
+ stack->data = NULL;
112
+ stack->depth = 0;
113
+ }
60
114
  }
61
115
 
116
+ #define STACK_INIT(uk) bool stack_allocated = _msgpack_unpacker_stack_init(&uk->stack);
117
+ #define STACK_FREE(uk) if (stack_allocated) { _msgpack_unpacker_free_stack(&uk->stack); }
118
+
62
119
  void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
63
120
  {
64
121
  msgpack_buffer_init(UNPACKER_BUFFER_(uk));
@@ -67,41 +124,38 @@ void _msgpack_unpacker_init(msgpack_unpacker_t* uk)
67
124
 
68
125
  uk->last_object = Qnil;
69
126
  uk->reading_raw = Qnil;
70
-
71
- uk->stack = _msgpack_unpacker_new_stack();
72
- }
73
-
74
- static inline void _msgpack_unpacker_free_stack(msgpack_unpacker_stack_t* stack) {
75
- if (!msgpack_rmem_free(&s_stack_rmem, stack->data)) {
76
- rb_bug("Failed to free an rmem pointer, memory leak?");
77
- }
78
- xfree(stack);
79
127
  }
80
128
 
81
129
  void _msgpack_unpacker_destroy(msgpack_unpacker_t* uk)
82
130
  {
83
- _msgpack_unpacker_free_stack(uk->stack);
131
+ _msgpack_unpacker_free_stack(&uk->stack);
84
132
  msgpack_buffer_destroy(UNPACKER_BUFFER_(uk));
85
133
  }
86
134
 
87
135
  void msgpack_unpacker_mark_stack(msgpack_unpacker_stack_t* stack)
88
136
  {
89
- while (stack) {
137
+ if (stack->data) {
90
138
  msgpack_unpacker_stack_entry_t* s = stack->data;
91
139
  msgpack_unpacker_stack_entry_t* send = stack->data + stack->depth;
92
140
  for(; s < send; s++) {
93
141
  rb_gc_mark(s->object);
94
142
  rb_gc_mark(s->key);
95
143
  }
96
- stack = stack->parent;
97
144
  }
98
145
  }
99
146
 
147
+ void msgpack_unpacker_mark_key_cache(msgpack_key_cache_t *cache)
148
+ {
149
+ const VALUE *entries = &cache->entries[0];
150
+ rb_gc_mark_locations(entries, entries + cache->length);
151
+ }
152
+
100
153
  void msgpack_unpacker_mark(msgpack_unpacker_t* uk)
101
154
  {
102
155
  rb_gc_mark(uk->last_object);
103
156
  rb_gc_mark(uk->reading_raw);
104
- msgpack_unpacker_mark_stack(uk->stack);
157
+ msgpack_unpacker_mark_stack(&uk->stack);
158
+ msgpack_unpacker_mark_key_cache(&uk->key_cache);
105
159
  /* See MessagePack_Buffer_wrap */
106
160
  /* msgpack_buffer_mark(UNPACKER_BUFFER_(uk)); */
107
161
  rb_gc_mark(uk->buffer_ref);
@@ -114,8 +168,8 @@ void _msgpack_unpacker_reset(msgpack_unpacker_t* uk)
114
168
 
115
169
  uk->head_byte = HEAD_BYTE_REQUIRED;
116
170
 
117
- /*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack->depth);*/
118
- uk->stack->depth = 0;
171
+ /*memset(uk->stack, 0, sizeof(msgpack_unpacker_t) * uk->stack.depth);*/
172
+ uk->stack.depth = 0;
119
173
  uk->last_object = Qnil;
120
174
  uk->reading_raw = Qnil;
121
175
  uk->reading_raw_remaining = 0;
@@ -179,7 +233,12 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
179
233
  if(proc != Qnil) {
180
234
  VALUE obj;
181
235
  VALUE arg = (str == Qnil ? rb_str_buf_new(0) : str);
182
- obj = rb_proc_call_with_block(proc, 1, &arg, Qnil);
236
+ int raised;
237
+ obj = protected_proc_call(proc, 1, &arg, &raised);
238
+ if (raised) {
239
+ uk->last_object = rb_errinfo();
240
+ return PRIMITIVE_RECURSIVE_RAISED;
241
+ }
183
242
  return object_complete(uk, obj);
184
243
  }
185
244
 
@@ -194,35 +253,35 @@ static inline int object_complete_ext(msgpack_unpacker_t* uk, int ext_type, VALU
194
253
  /* stack funcs */
195
254
  static inline msgpack_unpacker_stack_entry_t* _msgpack_unpacker_stack_entry_top(msgpack_unpacker_t* uk)
196
255
  {
197
- return &uk->stack->data[uk->stack->depth-1];
256
+ return &uk->stack.data[uk->stack.depth-1];
198
257
  }
199
258
 
200
259
  static inline int _msgpack_unpacker_stack_push(msgpack_unpacker_t* uk, enum stack_type_t type, size_t count, VALUE object)
201
260
  {
202
261
  reset_head_byte(uk);
203
262
 
204
- if(uk->stack->capacity - uk->stack->depth <= 0) {
263
+ if(uk->stack.capacity - uk->stack.depth <= 0) {
205
264
  return PRIMITIVE_STACK_TOO_DEEP;
206
265
  }
207
266
 
208
- msgpack_unpacker_stack_entry_t* next = &uk->stack->data[uk->stack->depth];
267
+ msgpack_unpacker_stack_entry_t* next = &uk->stack.data[uk->stack.depth];
209
268
  next->count = count;
210
269
  next->type = type;
211
270
  next->object = object;
212
271
  next->key = Qnil;
213
272
 
214
- uk->stack->depth++;
273
+ uk->stack.depth++;
215
274
  return PRIMITIVE_CONTAINER_START;
216
275
  }
217
276
 
218
- static inline VALUE msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk)
277
+ static inline size_t msgpack_unpacker_stack_pop(msgpack_unpacker_t* uk)
219
278
  {
220
- return --uk->stack->depth;
279
+ return --uk->stack.depth;
221
280
  }
222
281
 
223
282
  static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
224
283
  {
225
- return uk->stack->depth == 0;
284
+ return uk->stack.depth == 0;
226
285
  }
227
286
 
228
287
  #ifdef USE_CASE_RANGE
@@ -241,16 +300,29 @@ static inline bool msgpack_unpacker_stack_is_empty(msgpack_unpacker_t* uk)
241
300
 
242
301
  #endif
243
302
 
303
+ union msgpack_buffer_cast_block_t {
304
+ char buffer[8];
305
+ uint8_t u8;
306
+ uint16_t u16;
307
+ uint32_t u32;
308
+ uint64_t u64;
309
+ int8_t i8;
310
+ int16_t i16;
311
+ int32_t i32;
312
+ int64_t i64;
313
+ float f;
314
+ double d;
315
+ };
244
316
 
245
317
  #define READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, n) \
246
- union msgpack_buffer_cast_block_t* cb = msgpack_buffer_read_cast_block(UNPACKER_BUFFER_(uk), n); \
247
- if(cb == NULL) { \
318
+ union msgpack_buffer_cast_block_t cb; \
319
+ if (!msgpack_buffer_read_all(UNPACKER_BUFFER_(uk), (char *)&cb.buffer, n)) { \
248
320
  return PRIMITIVE_EOF; \
249
321
  }
250
322
 
251
323
  static inline bool is_reading_map_key(msgpack_unpacker_t* uk)
252
324
  {
253
- if(uk->stack->depth > 0) {
325
+ if(uk->stack.depth > 0) {
254
326
  msgpack_unpacker_stack_entry_t* top = _msgpack_unpacker_stack_entry_top(uk);
255
327
  if(top->type == STACK_TYPE_MAP_KEY) {
256
328
  return true;
@@ -264,7 +336,8 @@ static int read_raw_body_cont(msgpack_unpacker_t* uk)
264
336
  size_t length = uk->reading_raw_remaining;
265
337
 
266
338
  if(uk->reading_raw == Qnil) {
267
- uk->reading_raw = rb_str_buf_new(length);
339
+ size_t buffered_size = msgpack_buffer_all_readable_size(UNPACKER_BUFFER_(uk));
340
+ uk->reading_raw = rb_str_buf_new(length > buffered_size ? buffered_size : length);
268
341
  }
269
342
 
270
343
  do {
@@ -305,14 +378,15 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
305
378
  reset_head_byte(uk);
306
379
  uk->reading_raw_remaining = 0;
307
380
 
308
- msgpack_unpacker_stack_t* child_stack = _msgpack_unpacker_new_stack();
309
- child_stack->parent = uk->stack;
310
- uk->stack = child_stack;
311
-
312
- obj = rb_proc_call_with_block(proc, 1, &uk->self, Qnil);
381
+ _msgpack_unpacker_stack_push(uk, STACK_TYPE_RECURSIVE, 1, Qnil);
382
+ int raised;
383
+ obj = protected_proc_call(proc, 1, &uk->self, &raised);
384
+ msgpack_unpacker_stack_pop(uk);
313
385
 
314
- uk->stack = child_stack->parent;
315
- _msgpack_unpacker_free_stack(child_stack);
386
+ if (raised) {
387
+ uk->last_object = rb_errinfo();
388
+ return PRIMITIVE_RECURSIVE_RAISED;
389
+ }
316
390
 
317
391
  return object_complete(uk, obj);
318
392
  }
@@ -322,15 +396,32 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
322
396
  size_t length = uk->reading_raw_remaining;
323
397
  if(length <= msgpack_buffer_top_readable_size(UNPACKER_BUFFER_(uk))) {
324
398
  int ret;
325
- if ((uk->optimized_symbol_ext_type && uk->symbol_ext_type == raw_type) || (uk->symbolize_keys && is_reading_map_key(uk))) {
399
+ if ((uk->optimized_symbol_ext_type && uk->symbol_ext_type == raw_type)) {
326
400
  VALUE symbol = msgpack_buffer_read_top_as_symbol(UNPACKER_BUFFER_(uk), length, raw_type != RAW_TYPE_BINARY);
327
401
  ret = object_complete_symbol(uk, symbol);
402
+ } else if (is_reading_map_key(uk) && raw_type == RAW_TYPE_STRING) {
403
+ /* don't use zerocopy for hash keys but get a frozen string directly
404
+ * because rb_hash_aset freezes keys and it causes copying */
405
+ VALUE key;
406
+ if (uk->symbolize_keys) {
407
+ if (uk->use_key_cache) {
408
+ key = msgpack_buffer_read_top_as_interned_symbol(UNPACKER_BUFFER_(uk), &uk->key_cache, length);
409
+ } else {
410
+ key = msgpack_buffer_read_top_as_symbol(UNPACKER_BUFFER_(uk), length, true);
411
+ }
412
+ ret = object_complete_symbol(uk, key);
413
+ } else {
414
+ if (uk->use_key_cache) {
415
+ key = msgpack_buffer_read_top_as_interned_string(UNPACKER_BUFFER_(uk), &uk->key_cache, length);
416
+ } else {
417
+ key = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, true, true);
418
+ }
419
+
420
+ ret = object_complete(uk, key);
421
+ }
328
422
  } else {
329
423
  bool will_freeze = uk->freeze;
330
424
  if(raw_type == RAW_TYPE_STRING || raw_type == RAW_TYPE_BINARY) {
331
- /* don't use zerocopy for hash keys but get a frozen string directly
332
- * because rb_hash_aset freezes keys and it causes copying */
333
- will_freeze = will_freeze || is_reading_map_key(uk);
334
425
  VALUE string = msgpack_buffer_read_top_as_string(UNPACKER_BUFFER_(uk), length, will_freeze, raw_type == RAW_TYPE_STRING);
335
426
  ret = object_complete(uk, string);
336
427
  } else {
@@ -365,24 +456,24 @@ static int read_primitive(msgpack_unpacker_t* uk)
365
456
  return object_complete(uk, INT2NUM((int8_t)b));
366
457
 
367
458
  SWITCH_RANGE(b, 0xa0, 0xbf) // FixRaw / fixstr
368
- int count = b & 0x1f;
459
+ size_t count = b & 0x1f;
369
460
  /* read_raw_body_begin sets uk->reading_raw */
370
461
  uk->reading_raw_remaining = count;
371
462
  return read_raw_body_begin(uk, RAW_TYPE_STRING);
372
463
 
373
464
  SWITCH_RANGE(b, 0x90, 0x9f) // FixArray
374
- int count = b & 0x0f;
465
+ size_t count = b & 0x0f;
375
466
  if(count == 0) {
376
467
  return object_complete(uk, rb_ary_new());
377
468
  }
378
- return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(count));
469
+ return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(initial_buffer_size(count)));
379
470
 
380
471
  SWITCH_RANGE(b, 0x80, 0x8f) // FixMap
381
472
  int count = b & 0x0f;
382
473
  if(count == 0) {
383
474
  return object_complete(uk, rb_hash_new());
384
475
  }
385
- return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
476
+ return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(initial_buffer_size(count)));
386
477
 
387
478
  SWITCH_RANGE(b, 0xc0, 0xdf) // Variable
388
479
  switch(b) {
@@ -400,8 +491,8 @@ static int read_primitive(msgpack_unpacker_t* uk)
400
491
  case 0xc7: // ext 8
401
492
  {
402
493
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
403
- uint8_t length = cb->u8;
404
- int ext_type = (signed char) cb->buffer[1];
494
+ uint8_t length = cb.u8;
495
+ int ext_type = (signed char) cb.buffer[1];
405
496
  if(length == 0) {
406
497
  return object_complete_ext(uk, ext_type, Qnil);
407
498
  }
@@ -412,8 +503,8 @@ static int read_primitive(msgpack_unpacker_t* uk)
412
503
  case 0xc8: // ext 16
413
504
  {
414
505
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 3);
415
- uint16_t length = _msgpack_be16(cb->u16);
416
- int ext_type = (signed char) cb->buffer[2];
506
+ uint16_t length = _msgpack_be16(cb.u16);
507
+ int ext_type = (signed char) cb.buffer[2];
417
508
  if(length == 0) {
418
509
  return object_complete_ext(uk, ext_type, Qnil);
419
510
  }
@@ -424,8 +515,8 @@ static int read_primitive(msgpack_unpacker_t* uk)
424
515
  case 0xc9: // ext 32
425
516
  {
426
517
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 5);
427
- uint32_t length = _msgpack_be32(cb->u32);
428
- int ext_type = (signed char) cb->buffer[4];
518
+ uint32_t length = _msgpack_be32(cb.u32);
519
+ int ext_type = (signed char) cb.buffer[4];
429
520
  if(length == 0) {
430
521
  return object_complete_ext(uk, ext_type, Qnil);
431
522
  }
@@ -436,77 +527,77 @@ static int read_primitive(msgpack_unpacker_t* uk)
436
527
  case 0xca: // float
437
528
  {
438
529
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
439
- cb->u32 = _msgpack_be_float(cb->u32);
440
- return object_complete(uk, rb_float_new(cb->f));
530
+ cb.u32 = _msgpack_be_float(cb.u32);
531
+ return object_complete(uk, rb_float_new(cb.f));
441
532
  }
442
533
 
443
534
  case 0xcb: // double
444
535
  {
445
536
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 8);
446
- cb->u64 = _msgpack_be_double(cb->u64);
447
- return object_complete(uk, rb_float_new(cb->d));
537
+ cb.u64 = _msgpack_be_double(cb.u64);
538
+ return object_complete(uk, rb_float_new(cb.d));
448
539
  }
449
540
 
450
541
  case 0xcc: // unsigned int 8
451
542
  {
452
543
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
453
- uint8_t u8 = cb->u8;
544
+ uint8_t u8 = cb.u8;
454
545
  return object_complete(uk, INT2NUM((int)u8));
455
546
  }
456
547
 
457
548
  case 0xcd: // unsigned int 16
458
549
  {
459
550
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
460
- uint16_t u16 = _msgpack_be16(cb->u16);
551
+ uint16_t u16 = _msgpack_be16(cb.u16);
461
552
  return object_complete(uk, INT2NUM((int)u16));
462
553
  }
463
554
 
464
555
  case 0xce: // unsigned int 32
465
556
  {
466
557
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
467
- uint32_t u32 = _msgpack_be32(cb->u32);
558
+ uint32_t u32 = _msgpack_be32(cb.u32);
468
559
  return object_complete(uk, ULONG2NUM(u32)); // long at least 32 bits
469
560
  }
470
561
 
471
562
  case 0xcf: // unsigned int 64
472
563
  {
473
564
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 8);
474
- uint64_t u64 = _msgpack_be64(cb->u64);
565
+ uint64_t u64 = _msgpack_be64(cb.u64);
475
566
  return object_complete(uk, rb_ull2inum(u64));
476
567
  }
477
568
 
478
569
  case 0xd0: // signed int 8
479
570
  {
480
571
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
481
- int8_t i8 = cb->i8;
572
+ int8_t i8 = cb.i8;
482
573
  return object_complete(uk, INT2NUM((int)i8));
483
574
  }
484
575
 
485
576
  case 0xd1: // signed int 16
486
577
  {
487
578
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
488
- int16_t i16 = _msgpack_be16(cb->i16);
579
+ int16_t i16 = _msgpack_be16(cb.i16);
489
580
  return object_complete(uk, INT2NUM((int)i16));
490
581
  }
491
582
 
492
583
  case 0xd2: // signed int 32
493
584
  {
494
585
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
495
- int32_t i32 = _msgpack_be32(cb->i32);
586
+ int32_t i32 = _msgpack_be32(cb.i32);
496
587
  return object_complete(uk, LONG2NUM(i32)); // long at least 32 bits
497
588
  }
498
589
 
499
590
  case 0xd3: // signed int 64
500
591
  {
501
592
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 8);
502
- int64_t i64 = _msgpack_be64(cb->i64);
593
+ int64_t i64 = _msgpack_be64(cb.i64);
503
594
  return object_complete(uk, rb_ll2inum(i64));
504
595
  }
505
596
 
506
597
  case 0xd4: // fixext 1
507
598
  {
508
599
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
509
- int ext_type = cb->i8;
600
+ int ext_type = cb.i8;
510
601
  uk->reading_raw_remaining = 1;
511
602
  return read_raw_body_begin(uk, ext_type);
512
603
  }
@@ -514,7 +605,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
514
605
  case 0xd5: // fixext 2
515
606
  {
516
607
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
517
- int ext_type = cb->i8;
608
+ int ext_type = cb.i8;
518
609
  uk->reading_raw_remaining = 2;
519
610
  return read_raw_body_begin(uk, ext_type);
520
611
  }
@@ -522,7 +613,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
522
613
  case 0xd6: // fixext 4
523
614
  {
524
615
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
525
- int ext_type = cb->i8;
616
+ int ext_type = cb.i8;
526
617
  uk->reading_raw_remaining = 4;
527
618
  return read_raw_body_begin(uk, ext_type);
528
619
  }
@@ -530,7 +621,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
530
621
  case 0xd7: // fixext 8
531
622
  {
532
623
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
533
- int ext_type = cb->i8;
624
+ int ext_type = cb.i8;
534
625
  uk->reading_raw_remaining = 8;
535
626
  return read_raw_body_begin(uk, ext_type);
536
627
  }
@@ -538,7 +629,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
538
629
  case 0xd8: // fixext 16
539
630
  {
540
631
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
541
- int ext_type = cb->i8;
632
+ int ext_type = cb.i8;
542
633
  uk->reading_raw_remaining = 16;
543
634
  return read_raw_body_begin(uk, ext_type);
544
635
  }
@@ -547,7 +638,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
547
638
  case 0xd9: // raw 8 / str 8
548
639
  {
549
640
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
550
- uint8_t count = cb->u8;
641
+ size_t count = cb.u8;
551
642
  /* read_raw_body_begin sets uk->reading_raw */
552
643
  uk->reading_raw_remaining = count;
553
644
  return read_raw_body_begin(uk, RAW_TYPE_STRING);
@@ -556,7 +647,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
556
647
  case 0xda: // raw 16 / str 16
557
648
  {
558
649
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
559
- uint16_t count = _msgpack_be16(cb->u16);
650
+ size_t count = _msgpack_be16(cb.u16);
560
651
  /* read_raw_body_begin sets uk->reading_raw */
561
652
  uk->reading_raw_remaining = count;
562
653
  return read_raw_body_begin(uk, RAW_TYPE_STRING);
@@ -565,7 +656,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
565
656
  case 0xdb: // raw 32 / str 32
566
657
  {
567
658
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
568
- uint32_t count = _msgpack_be32(cb->u32);
659
+ size_t count = _msgpack_be32(cb.u32);
569
660
  /* read_raw_body_begin sets uk->reading_raw */
570
661
  uk->reading_raw_remaining = count;
571
662
  return read_raw_body_begin(uk, RAW_TYPE_STRING);
@@ -574,7 +665,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
574
665
  case 0xc4: // bin 8
575
666
  {
576
667
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 1);
577
- uint8_t count = cb->u8;
668
+ size_t count = cb.u8;
578
669
  /* read_raw_body_begin sets uk->reading_raw */
579
670
  uk->reading_raw_remaining = count;
580
671
  return read_raw_body_begin(uk, RAW_TYPE_BINARY);
@@ -583,7 +674,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
583
674
  case 0xc5: // bin 16
584
675
  {
585
676
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
586
- uint16_t count = _msgpack_be16(cb->u16);
677
+ size_t count = _msgpack_be16(cb.u16);
587
678
  /* read_raw_body_begin sets uk->reading_raw */
588
679
  uk->reading_raw_remaining = count;
589
680
  return read_raw_body_begin(uk, RAW_TYPE_BINARY);
@@ -592,7 +683,7 @@ static int read_primitive(msgpack_unpacker_t* uk)
592
683
  case 0xc6: // bin 32
593
684
  {
594
685
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
595
- uint32_t count = _msgpack_be32(cb->u32);
686
+ size_t count = _msgpack_be32(cb.u32);
596
687
  /* read_raw_body_begin sets uk->reading_raw */
597
688
  uk->reading_raw_remaining = count;
598
689
  return read_raw_body_begin(uk, RAW_TYPE_BINARY);
@@ -601,41 +692,41 @@ static int read_primitive(msgpack_unpacker_t* uk)
601
692
  case 0xdc: // array 16
602
693
  {
603
694
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
604
- uint16_t count = _msgpack_be16(cb->u16);
695
+ size_t count = _msgpack_be16(cb.u16);
605
696
  if(count == 0) {
606
697
  return object_complete(uk, rb_ary_new());
607
698
  }
608
- return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(count));
699
+ return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(initial_buffer_size(count)));
609
700
  }
610
701
 
611
702
  case 0xdd: // array 32
612
703
  {
613
704
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
614
- uint32_t count = _msgpack_be32(cb->u32);
705
+ size_t count = _msgpack_be32(cb.u32);
615
706
  if(count == 0) {
616
707
  return object_complete(uk, rb_ary_new());
617
708
  }
618
- return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(count));
709
+ return _msgpack_unpacker_stack_push(uk, STACK_TYPE_ARRAY, count, rb_ary_new2(initial_buffer_size(count)));
619
710
  }
620
711
 
621
712
  case 0xde: // map 16
622
713
  {
623
714
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
624
- uint16_t count = _msgpack_be16(cb->u16);
715
+ size_t count = _msgpack_be16(cb.u16);
625
716
  if(count == 0) {
626
717
  return object_complete(uk, rb_hash_new());
627
718
  }
628
- return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
719
+ return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(initial_buffer_size(count)));
629
720
  }
630
721
 
631
722
  case 0xdf: // map 32
632
723
  {
633
724
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
634
- uint32_t count = _msgpack_be32(cb->u32);
725
+ size_t count = _msgpack_be32(cb.u32);
635
726
  if(count == 0) {
636
727
  return object_complete(uk, rb_hash_new());
637
728
  }
638
- return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(count));
729
+ return _msgpack_unpacker_stack_push(uk, STACK_TYPE_MAP_KEY, count*2, rb_hash_new_capa(initial_buffer_size(count)));
639
730
  }
640
731
 
641
732
  default:
@@ -661,12 +752,12 @@ int msgpack_unpacker_read_array_header(msgpack_unpacker_t* uk, uint32_t* result_
661
752
  } else if(b == 0xdc) {
662
753
  /* array 16 */
663
754
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
664
- *result_size = _msgpack_be16(cb->u16);
755
+ *result_size = _msgpack_be16(cb.u16);
665
756
 
666
757
  } else if(b == 0xdd) {
667
758
  /* array 32 */
668
759
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
669
- *result_size = _msgpack_be32(cb->u32);
760
+ *result_size = _msgpack_be32(cb.u32);
670
761
 
671
762
  } else {
672
763
  return PRIMITIVE_UNEXPECTED_TYPE;
@@ -689,12 +780,12 @@ int msgpack_unpacker_read_map_header(msgpack_unpacker_t* uk, uint32_t* result_si
689
780
  } else if(b == 0xde) {
690
781
  /* map 16 */
691
782
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 2);
692
- *result_size = _msgpack_be16(cb->u16);
783
+ *result_size = _msgpack_be16(cb.u16);
693
784
 
694
785
  } else if(b == 0xdf) {
695
786
  /* map 32 */
696
787
  READ_CAST_BLOCK_OR_RETURN_EOF(cb, uk, 4);
697
- *result_size = _msgpack_be32(cb->u32);
788
+ *result_size = _msgpack_be32(cb.u32);
698
789
 
699
790
  } else {
700
791
  return PRIMITIVE_UNEXPECTED_TYPE;
@@ -706,9 +797,15 @@ int msgpack_unpacker_read_map_header(msgpack_unpacker_t* uk, uint32_t* result_si
706
797
 
707
798
  int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
708
799
  {
800
+ STACK_INIT(uk);
801
+
709
802
  while(true) {
710
803
  int r = read_primitive(uk);
711
804
  if(r < 0) {
805
+ if (r != PRIMITIVE_EOF) {
806
+ // We keep the stack on EOF as the parsing may be resumed.
807
+ STACK_FREE(uk);
808
+ }
712
809
  return r;
713
810
  }
714
811
  if(r == PRIMITIVE_CONTAINER_START) {
@@ -717,6 +814,7 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
717
814
  /* PRIMITIVE_OBJECT_COMPLETE */
718
815
 
719
816
  if(msgpack_unpacker_stack_is_empty(uk)) {
817
+ STACK_FREE(uk);
720
818
  return PRIMITIVE_OBJECT_COMPLETE;
721
819
  }
722
820
 
@@ -740,12 +838,16 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
740
838
  }
741
839
  top->type = STACK_TYPE_MAP_KEY;
742
840
  break;
841
+ case STACK_TYPE_RECURSIVE:
842
+ STACK_FREE(uk);
843
+ return PRIMITIVE_OBJECT_COMPLETE;
743
844
  }
744
845
  size_t count = --top->count;
745
846
 
746
847
  if(count == 0) {
747
848
  object_complete(uk, top->object);
748
849
  if(msgpack_unpacker_stack_pop(uk) <= target_stack_depth) {
850
+ STACK_FREE(uk);
749
851
  return PRIMITIVE_OBJECT_COMPLETE;
750
852
  }
751
853
  goto container_completed;
@@ -756,9 +858,12 @@ int msgpack_unpacker_read(msgpack_unpacker_t* uk, size_t target_stack_depth)
756
858
 
757
859
  int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
758
860
  {
861
+ STACK_INIT(uk);
862
+
759
863
  while(true) {
760
864
  int r = read_primitive(uk);
761
865
  if(r < 0) {
866
+ STACK_FREE(uk);
762
867
  return r;
763
868
  }
764
869
  if(r == PRIMITIVE_CONTAINER_START) {
@@ -767,6 +872,7 @@ int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
767
872
  /* PRIMITIVE_OBJECT_COMPLETE */
768
873
 
769
874
  if(msgpack_unpacker_stack_is_empty(uk)) {
875
+ STACK_FREE(uk);
770
876
  return PRIMITIVE_OBJECT_COMPLETE;
771
877
  }
772
878
 
@@ -782,6 +888,7 @@ int msgpack_unpacker_skip(msgpack_unpacker_t* uk, size_t target_stack_depth)
782
888
  if(count == 0) {
783
889
  object_complete(uk, Qnil);
784
890
  if(msgpack_unpacker_stack_pop(uk) <= target_stack_depth) {
891
+ STACK_FREE(uk);
785
892
  return PRIMITIVE_OBJECT_COMPLETE;
786
893
  }
787
894
  goto container_completed;