@@ -516,7 +516,7 @@ fn read_const_value<R: Read, Bag: ConstantBag>(
516516 let code = deserialize_code_inner ( rdr, bag, depth - 1 , refs) ?;
517517 bag. make_code ( code)
518518 } else {
519- deserialize_value_typed ( rdr, bag, depth, refs, typ) ?
519+ deserialize_value_typed ( rdr, bag, depth, refs, typ, slot ) ?
520520 } ;
521521 if let Some ( idx) = slot {
522522 refs[ idx] = Some ( value. clone ( ) ) ;
@@ -540,6 +540,10 @@ pub trait MarshalBag: Copy {
540540
541541 fn make_str ( & self , value : & Wtf8 ) -> Self :: Value ;
542542
543+ fn make_interned_str ( & self , value : & Wtf8 ) -> Self :: Value {
544+ self . make_str ( value)
545+ }
546+
543547 fn make_bytes ( & self , value : & [ u8 ] ) -> Self :: Value ;
544548
545549 fn make_int ( & self , value : BigInt ) -> Self :: Value ;
@@ -564,6 +568,51 @@ pub trait MarshalBag: Copy {
564568 it : impl Iterator < Item = ( Self :: Value , Self :: Value ) > ,
565569 ) -> Result < Self :: Value > ;
566570
571+ /// Install partially-built containers in the marshal reference table
572+ /// before reading their children, as CPython's `r_object()` does.
573+ /// Runtime bags can opt in; constant bags retain collect-then-construct.
574+ fn make_tuple_placeholder ( & self , _len : usize ) -> Option < Self :: Value > {
575+ None
576+ }
577+
578+ fn set_tuple_item (
579+ & self ,
580+ _tuple : & Self :: Value ,
581+ _index : usize ,
582+ _value : Self :: Value ,
583+ ) -> Result < ( ) > {
584+ Err ( MarshalError :: BadType )
585+ }
586+
587+ fn make_list_placeholder ( & self , _len : usize ) -> Option < Self :: Value > {
588+ None
589+ }
590+
591+ fn set_list_item ( & self , _list : & Self :: Value , _index : usize , _value : Self :: Value ) -> Result < ( ) > {
592+ Err ( MarshalError :: BadType )
593+ }
594+
595+ fn make_set_placeholder ( & self ) -> Option < Self :: Value > {
596+ None
597+ }
598+
599+ fn insert_set_item ( & self , _set : & Self :: Value , _value : Self :: Value ) -> Result < ( ) > {
600+ Err ( MarshalError :: BadType )
601+ }
602+
603+ fn make_dict_placeholder ( & self ) -> Option < Self :: Value > {
604+ None
605+ }
606+
607+ fn insert_dict_item (
608+ & self ,
609+ _dict : & Self :: Value ,
610+ _key : Self :: Value ,
611+ _value : Self :: Value ,
612+ ) -> Result < ( ) > {
613+ Err ( MarshalError :: BadType )
614+ }
615+
567616 fn make_slice (
568617 & self ,
569618 _start : Self :: Value ,
@@ -755,7 +804,7 @@ fn deserialize_value_after_header<R: Read, Bag: MarshalBag>(
755804 let code = deserialize_code_inner ( rdr, bag. constant_bag ( ) , depth - 1 , & mut inner_refs) ?;
756805 bag. make_code ( code)
757806 } else {
758- deserialize_value_typed ( rdr, bag, depth, refs, typ) ?
807+ deserialize_value_typed ( rdr, bag, depth, refs, typ, slot ) ?
759808 } ;
760809
761810 if let Some ( idx) = slot {
@@ -770,6 +819,7 @@ fn deserialize_value_typed<R: Read, Bag: MarshalBag>(
770819 depth : usize ,
771820 refs : & mut Vec < Option < Bag :: Value > > ,
772821 typ : Type ,
822+ slot : Option < usize > ,
773823) -> Result < Bag :: Value > {
774824 if depth == 0 {
775825 return Err ( MarshalError :: InvalidBytecode ) ;
@@ -806,21 +856,42 @@ fn deserialize_value_typed<R: Read, Bag: MarshalBag>(
806856 let value = Complex64 { re, im } ;
807857 bag. make_complex ( value)
808858 }
809- Type :: Ascii | Type :: AsciiInterned | Type :: Unicode | Type :: Interned => {
859+ Type :: Ascii | Type :: Unicode => {
810860 let len = rdr. read_u32 ( ) ?;
811861 let value = rdr. read_wtf8 ( len) ?;
812862 bag. make_str ( value)
813863 }
814- Type :: ShortAscii | Type :: ShortAsciiInterned => {
864+ Type :: AsciiInterned | Type :: Interned => {
865+ let len = rdr. read_u32 ( ) ?;
866+ let value = rdr. read_wtf8 ( len) ?;
867+ bag. make_interned_str ( value)
868+ }
869+ Type :: ShortAscii => {
815870 let len = rdr. read_u8 ( ) ? as u32 ;
816871 let value = rdr. read_wtf8 ( len) ?;
817872 bag. make_str ( value)
818873 }
874+ Type :: ShortAsciiInterned => {
875+ let len = rdr. read_u8 ( ) ? as u32 ;
876+ let value = rdr. read_wtf8 ( len) ?;
877+ bag. make_interned_str ( value)
878+ }
819879 Type :: SmallTuple => {
820880 let len = rdr. read_u8 ( ) ? as usize ;
821881 let d = depth - 1 ;
822- let it = ( 0 ..len) . map ( |_| deserialize_value_depth ( rdr, bag, d, refs) ) ;
823- itertools:: process_results ( it, |it| bag. make_tuple ( it) ) ?
882+ if let Some ( index) = slot
883+ && let Some ( tuple) = bag. make_tuple_placeholder ( len)
884+ {
885+ refs[ index] = Some ( tuple. clone ( ) ) ;
886+ for item_index in 0 ..len {
887+ let item = deserialize_value_depth ( rdr, bag, d, refs) ?;
888+ bag. set_tuple_item ( & tuple, item_index, item) ?;
889+ }
890+ tuple
891+ } else {
892+ let it = ( 0 ..len) . map ( |_| deserialize_value_depth ( rdr, bag, d, refs) ) ;
893+ itertools:: process_results ( it, |it| bag. make_tuple ( it) ) ?
894+ }
824895 }
825896 Type :: Null => {
826897 return Err ( MarshalError :: BadType ) ;
@@ -830,22 +901,55 @@ fn deserialize_value_typed<R: Read, Bag: MarshalBag>(
830901 return Err ( MarshalError :: BadType ) ;
831902 }
832903 Type :: Tuple => {
833- let len = rdr. read_u32 ( ) ?;
904+ let len = rdr. read_u32 ( ) ? as usize ;
834905 let d = depth - 1 ;
835- let it = ( 0 ..len) . map ( |_| deserialize_value_depth ( rdr, bag, d, refs) ) ;
836- itertools:: process_results ( it, |it| bag. make_tuple ( it) ) ?
906+ if let Some ( index) = slot
907+ && let Some ( tuple) = bag. make_tuple_placeholder ( len)
908+ {
909+ refs[ index] = Some ( tuple. clone ( ) ) ;
910+ for item_index in 0 ..len {
911+ let item = deserialize_value_depth ( rdr, bag, d, refs) ?;
912+ bag. set_tuple_item ( & tuple, item_index, item) ?;
913+ }
914+ tuple
915+ } else {
916+ let it = ( 0 ..len) . map ( |_| deserialize_value_depth ( rdr, bag, d, refs) ) ;
917+ itertools:: process_results ( it, |it| bag. make_tuple ( it) ) ?
918+ }
837919 }
838920 Type :: List => {
839- let len = rdr. read_u32 ( ) ?;
921+ let len = rdr. read_u32 ( ) ? as usize ;
840922 let d = depth - 1 ;
841- let it = ( 0 ..len) . map ( |_| deserialize_value_depth ( rdr, bag, d, refs) ) ;
842- itertools:: process_results ( it, |it| bag. make_list ( it) ) ??
923+ if let Some ( index) = slot
924+ && let Some ( list) = bag. make_list_placeholder ( len)
925+ {
926+ refs[ index] = Some ( list. clone ( ) ) ;
927+ for item_index in 0 ..len {
928+ let item = deserialize_value_depth ( rdr, bag, d, refs) ?;
929+ bag. set_list_item ( & list, item_index, item) ?;
930+ }
931+ list
932+ } else {
933+ let it = ( 0 ..len) . map ( |_| deserialize_value_depth ( rdr, bag, d, refs) ) ;
934+ itertools:: process_results ( it, |it| bag. make_list ( it) ) ??
935+ }
843936 }
844937 Type :: Set => {
845- let len = rdr. read_u32 ( ) ?;
938+ let len = rdr. read_u32 ( ) ? as usize ;
846939 let d = depth - 1 ;
847- let it = ( 0 ..len) . map ( |_| deserialize_value_depth ( rdr, bag, d, refs) ) ;
848- itertools:: process_results ( it, |it| bag. make_set ( it) ) ??
940+ if let Some ( index) = slot
941+ && let Some ( set) = bag. make_set_placeholder ( )
942+ {
943+ refs[ index] = Some ( set. clone ( ) ) ;
944+ for _ in 0 ..len {
945+ let item = deserialize_value_depth ( rdr, bag, d, refs) ?;
946+ bag. insert_set_item ( & set, item) ?;
947+ }
948+ set
949+ } else {
950+ let it = ( 0 ..len) . map ( |_| deserialize_value_depth ( rdr, bag, d, refs) ) ;
951+ itertools:: process_results ( it, |it| bag. make_set ( it) ) ??
952+ }
849953 }
850954 Type :: FrozenSet => {
851955 let len = rdr. read_u32 ( ) ?;
@@ -855,17 +959,33 @@ fn deserialize_value_typed<R: Read, Bag: MarshalBag>(
855959 }
856960 Type :: Dict => {
857961 let d = depth - 1 ;
858- let mut pairs = Vec :: new ( ) ;
859- loop {
860- let raw = rdr. read_u8 ( ) ?;
861- if raw & !FLAG_REF == b'0' {
862- break ;
962+ if let Some ( index) = slot
963+ && let Some ( dict) = bag. make_dict_placeholder ( )
964+ {
965+ refs[ index] = Some ( dict. clone ( ) ) ;
966+ loop {
967+ let raw = rdr. read_u8 ( ) ?;
968+ if raw & !FLAG_REF == b'0' {
969+ break ;
970+ }
971+ let key = deserialize_value_after_header ( rdr, bag, d, refs, raw) ?;
972+ let value = deserialize_value_depth ( rdr, bag, d, refs) ?;
973+ bag. insert_dict_item ( & dict, key, value) ?;
974+ }
975+ dict
976+ } else {
977+ let mut pairs = Vec :: new ( ) ;
978+ loop {
979+ let raw = rdr. read_u8 ( ) ?;
980+ if raw & !FLAG_REF == b'0' {
981+ break ;
982+ }
983+ let key = deserialize_value_after_header ( rdr, bag, d, refs, raw) ?;
984+ let value = deserialize_value_depth ( rdr, bag, d, refs) ?;
985+ pairs. push ( ( key, value) ) ;
863986 }
864- let k = deserialize_value_after_header ( rdr, bag, d, refs, raw) ?;
865- let v = deserialize_value_depth ( rdr, bag, d, refs) ?;
866- pairs. push ( ( k, v) ) ;
987+ bag. make_dict ( pairs. into_iter ( ) ) ?
867988 }
868- bag. make_dict ( pairs. into_iter ( ) ) ?
869989 }
870990 Type :: Bytes => {
871991 // After marshaling, byte arrays are converted into bytes.
0 commit comments