@@ -489,57 +489,21 @@ static inline int read_raw_body_begin(msgpack_unpacker_t* uk, int raw_type)
489489 reset_head_byte (uk );
490490 uk -> reading_raw_remaining = 0 ;
491491
492- /* Get struct members */
493- VALUE members = rb_struct_s_members (struct_class );
494- long num_fields = RARRAY_LEN (members );
495-
496- /* Check if this is a keyword_init struct (Ruby 2.7+) */
497- VALUE keyword_init = Qfalse ;
498- if (rb_respond_to (struct_class , rb_intern ("keyword_init?" ))) {
499- keyword_init = rb_funcall (struct_class , rb_intern ("keyword_init?" ), 0 );
500- }
501-
502492 /* Push a recursive marker so nested reads don't prematurely return */
503493 _msgpack_unpacker_stack_push (uk , STACK_TYPE_RECURSIVE , 1 , Qnil );
504494
505- VALUE obj ;
506- if (num_fields == 0 ) {
507- /* Special case for empty structs */
508- obj = rb_class_new_instance (0 , NULL , struct_class );
509- } else if (RTEST (keyword_init )) {
510- /* For keyword_init structs, build a hash with member names as keys */
511- VALUE kwargs = rb_hash_new ();
512- for (long i = 0 ; i < num_fields ; i ++ ) {
513- int ret = msgpack_unpacker_read (uk , 0 );
514- if (ret < 0 ) {
515- msgpack_unpacker_stack_pop (uk );
516- return ret ;
517- }
518- VALUE key = rb_ary_entry (members , i );
519- rb_hash_aset (kwargs , key , uk -> last_object );
520- }
521- /* Call new with keyword arguments */
522- obj = rb_class_new_instance_kw (1 , & kwargs , struct_class , RB_PASS_KEYWORDS );
523- } else {
524- /* For regular structs, use positional arguments
525- * Use RB_ALLOCV to avoid stack overflow with large structs */
526- VALUE allocv_holder ;
527- VALUE * values = RB_ALLOCV_N (VALUE , allocv_holder , num_fields );
528- for (int i = 0 ; i < num_fields ; i ++ ) {
529- int ret = msgpack_unpacker_read (uk , 0 );
530- if (ret < 0 ) {
531- msgpack_unpacker_stack_pop (uk );
532- RB_ALLOCV_END (allocv_holder );
533- return ret ;
534- }
535- values [i ] = uk -> last_object ;
495+ VALUE obj = rb_obj_alloc (struct_class );
496+ long num_fields = RSTRUCT_LEN (obj );
497+
498+ for (int i = 0 ; i < num_fields ; i ++ ) {
499+ int ret = msgpack_unpacker_read (uk , 0 );
500+ if (RB_UNLIKELY (ret < 0 )) {
501+ msgpack_unpacker_stack_pop (uk );
502+ return ret ;
536503 }
537- obj = rb_class_new_instance ((int )num_fields , values , struct_class );
538- RB_ALLOCV_END (allocv_holder );
504+ RSTRUCT_SET (obj , i , uk -> last_object );
539505 }
540506
541- RB_GC_GUARD (struct_class );
542- RB_GC_GUARD (members );
543507 msgpack_unpacker_stack_pop (uk );
544508 return object_complete (uk , obj );
545509 }
0 commit comments