msgpack 1.7.1 → 1.8.0

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