@@ -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 )
@@ -291,8 +298,12 @@ static void rvalue_stack_eagerly_release(VALUE handle)
291298 if (handle ) {
292299 rvalue_stack * stack ;
293300 TypedData_Get_Struct (handle , rvalue_stack , & JSON_Parser_rvalue_stack_type , stack );
294- RTYPEDDATA_DATA (handle ) = NULL ;
301+ #ifdef HAVE_RUBY_TYPED_EMBEDDABLE
302+ rvalue_stack_free_buffer (stack );
303+ #else
295304 rvalue_stack_free (stack );
305+ RTYPEDDATA_DATA (handle ) = NULL ;
306+ #endif
296307 }
297308}
298309
@@ -343,7 +354,7 @@ typedef struct JSON_ParserStruct {
343354} JSON_ParserConfig ;
344355
345356typedef struct JSON_ParserStateStruct {
346- VALUE stack_handle ;
357+ VALUE * stack_handle ;
347358 const char * start ;
348359 const char * cursor ;
349360 const char * end ;
@@ -944,7 +955,7 @@ static inline VALUE json_push_value(JSON_ParserState *state, JSON_ParserConfig *
944955 if (RB_UNLIKELY (config -> on_load_proc )) {
945956 value = rb_proc_call_with_block (config -> on_load_proc , 1 , & value , Qnil );
946957 }
947- rvalue_stack_push (state -> stack , value , & state -> stack_handle , & state -> stack );
958+ rvalue_stack_push (state -> stack , value , state -> stack_handle , & state -> stack );
948959 return value ;
949960}
950961
@@ -1554,20 +1565,22 @@ static VALUE cParser_parse(JSON_ParserConfig *config, VALUE Vsource)
15541565 const char * start ;
15551566 RSTRING_GETMEM (Vsource , start , len );
15561567
1568+ VALUE stack_handle = 0 ;
15571569 JSON_ParserState _state = {
15581570 .start = start ,
15591571 .cursor = start ,
15601572 .end = start + len ,
15611573 .stack = & stack ,
1574+ .stack_handle = & stack_handle ,
15621575 };
15631576 JSON_ParserState * state = & _state ;
15641577
15651578 VALUE result = json_parse_any (state , config );
15661579
15671580 // This may be skipped in case of exception, but
15681581 // it won't cause a leak.
1569- rvalue_stack_eagerly_release (state -> stack_handle );
1570-
1582+ rvalue_stack_eagerly_release (stack_handle );
1583+ RB_GC_GUARD ( stack_handle );
15711584 json_ensure_eof (state );
15721585
15731586 return result ;
@@ -1605,26 +1618,19 @@ static void JSON_ParserConfig_mark(void *ptr)
16051618 rb_gc_mark (config -> decimal_class );
16061619}
16071620
1608- static void JSON_ParserConfig_free (void * ptr )
1609- {
1610- JSON_ParserConfig * config = ptr ;
1611- ruby_xfree (config );
1612- }
1613-
16141621static size_t JSON_ParserConfig_memsize (const void * ptr )
16151622{
16161623 return sizeof (JSON_ParserConfig );
16171624}
16181625
16191626static const rb_data_type_t JSON_ParserConfig_type = {
1620- "JSON::Ext::Parser/ParserConfig" ,
1621- {
1627+ . wrap_struct_name = "JSON::Ext::Parser/ParserConfig" ,
1628+ . function = {
16221629 JSON_ParserConfig_mark ,
1623- JSON_ParserConfig_free ,
1630+ RUBY_DEFAULT_FREE ,
16241631 JSON_ParserConfig_memsize ,
16251632 },
1626- 0 , 0 ,
1627- RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE ,
1633+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_EMBEDDABLE ,
16281634};
16291635
16301636static VALUE cJSON_parser_s_allocate (VALUE klass )
0 commit comments