@@ -246,12 +246,20 @@ static void rvalue_stack_mark(void *ptr)
246246 }
247247}
248248
249+ static void rvalue_stack_free_buffer (rvalue_stack * stack )
250+ {
251+ ruby_xfree (stack -> ptr );
252+ stack -> ptr = NULL ;
253+ }
254+
249255static void rvalue_stack_free (void * ptr )
250256{
251257 rvalue_stack * stack = (rvalue_stack * )ptr ;
252258 if (stack ) {
253- ruby_xfree (stack -> ptr );
259+ rvalue_stack_free_buffer (stack );
260+ #ifndef HAVE_RUBY_TYPED_EMBEDDABLE
254261 ruby_xfree (stack );
262+ #endif
255263 }
256264}
257265
@@ -262,14 +270,13 @@ static size_t rvalue_stack_memsize(const void *ptr)
262270}
263271
264272static const rb_data_type_t JSON_Parser_rvalue_stack_type = {
265- "JSON::Ext::Parser/rvalue_stack" ,
266- {
273+ . wrap_struct_name = "JSON::Ext::Parser/rvalue_stack" ,
274+ . function = {
267275 .dmark = rvalue_stack_mark ,
268276 .dfree = rvalue_stack_free ,
269277 .dsize = rvalue_stack_memsize ,
270278 },
271- 0 , 0 ,
272- RUBY_TYPED_FREE_IMMEDIATELY ,
279+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_EMBEDDABLE ,
273280};
274281
275282static rvalue_stack * rvalue_stack_spill (rvalue_stack * old_stack , VALUE * handle , rvalue_stack * * stack_ref )
@@ -281,6 +288,7 @@ static rvalue_stack *rvalue_stack_spill(rvalue_stack *old_stack, VALUE *handle,
281288
282289 stack -> capa = old_stack -> capa << 1 ;
283290 stack -> ptr = ALLOC_N (VALUE , stack -> capa );
291+
284292 stack -> type = RVALUE_STACK_HEAP_ALLOCATED ;
285293 MEMCPY (stack -> ptr , old_stack -> ptr , VALUE , old_stack -> head );
286294 return stack ;
@@ -291,8 +299,12 @@ static void rvalue_stack_eagerly_release(VALUE handle)
291299 if (handle ) {
292300 rvalue_stack * stack ;
293301 TypedData_Get_Struct (handle , rvalue_stack , & JSON_Parser_rvalue_stack_type , stack );
294- RTYPEDDATA_DATA (handle ) = NULL ;
302+ #ifdef HAVE_RUBY_TYPED_EMBEDDABLE
303+ rvalue_stack_free_buffer (stack );
304+ #else
295305 rvalue_stack_free (stack );
306+ RTYPEDDATA_DATA (handle ) = NULL ;
307+ #endif
296308 }
297309}
298310
@@ -343,7 +355,7 @@ typedef struct JSON_ParserStruct {
343355} JSON_ParserConfig ;
344356
345357typedef struct JSON_ParserStateStruct {
346- VALUE stack_handle ;
358+ VALUE * stack_handle ;
347359 const char * start ;
348360 const char * cursor ;
349361 const char * end ;
@@ -944,7 +956,7 @@ static inline VALUE json_push_value(JSON_ParserState *state, JSON_ParserConfig *
944956 if (RB_UNLIKELY (config -> on_load_proc )) {
945957 value = rb_proc_call_with_block (config -> on_load_proc , 1 , & value , Qnil );
946958 }
947- rvalue_stack_push (state -> stack , value , & state -> stack_handle , & state -> stack );
959+ rvalue_stack_push (state -> stack , value , state -> stack_handle , & state -> stack );
948960 return value ;
949961}
950962
@@ -1554,20 +1566,22 @@ static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource)
15541566 const char * start ;
15551567 RSTRING_GETMEM (Vsource , start , len );
15561568
1569+ VALUE stack_handle = 0 ;
15571570 JSON_ParserState _state = {
15581571 .start = start ,
15591572 .cursor = start ,
15601573 .end = start + len ,
15611574 .stack = & stack ,
1575+ .stack_handle = & stack_handle ,
15621576 };
15631577 JSON_ParserState * state = & _state ;
15641578
15651579 VALUE result = json_parse_any (state , config );
15661580
15671581 // This may be skipped in case of exception, but
15681582 // it won't cause a leak.
1569- rvalue_stack_eagerly_release (state -> stack_handle );
1570-
1583+ rvalue_stack_eagerly_release (stack_handle );
1584+ RB_GC_GUARD ( stack_handle );
15711585 json_ensure_eof (state );
15721586
15731587 return result ;
@@ -1605,26 +1619,19 @@ static void JSON_ParserConfig_mark(void *ptr)
16051619 rb_gc_mark (config -> decimal_class );
16061620}
16071621
1608- static void JSON_ParserConfig_free (void * ptr )
1609- {
1610- JSON_ParserConfig * config = ptr ;
1611- ruby_xfree (config );
1612- }
1613-
16141622static size_t JSON_ParserConfig_memsize (const void * ptr )
16151623{
16161624 return sizeof (JSON_ParserConfig );
16171625}
16181626
16191627static const rb_data_type_t JSON_ParserConfig_type = {
1620- "JSON::Ext::Parser/ParserConfig" ,
1621- {
1628+ . wrap_struct_name = "JSON::Ext::Parser/ParserConfig" ,
1629+ . function = {
16221630 JSON_ParserConfig_mark ,
1623- JSON_ParserConfig_free ,
1631+ RUBY_DEFAULT_FREE ,
16241632 JSON_ParserConfig_memsize ,
16251633 },
1626- 0 , 0 ,
1627- RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE ,
1634+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_EMBEDDABLE ,
16281635};
16291636
16301637static VALUE cJSON_parser_s_allocate (VALUE klass )
0 commit comments