@@ -652,6 +652,75 @@ void AddFieldModification(MethodDefinition method, Dictionary<string, HashSet<In
652652
653653 HashSet < Instruction > extractedStaticInsts = [ ] ;
654654
655+ if ( method . Name == "FillResearchItemOverrides" ) {
656+
657+ }
658+
659+ bool UsedStaticField ( MethodDefinition method ) {
660+ HashSet < string > visited = [ ] ;
661+ Stack < MethodDefinition > stack = [ ] ;
662+
663+ stack . Push ( method ) ;
664+ visited . Add ( method . GetIdentifier ( ) ) ;
665+
666+ while ( stack . Count > 0 ) {
667+ var caller = stack . Pop ( ) ;
668+
669+ foreach ( var inst in caller . Body . Instructions ) {
670+ if ( inst . OpCode == OpCodes . Ldsflda || inst . OpCode == OpCodes . Stsfld ) {
671+ return true ;
672+ }
673+ if ( inst . OpCode == OpCodes . Ldsfld ) {
674+ var field = ( ( FieldReference ) inst . Operand ) ;
675+ if ( ! field . FieldType . IsTruelyValueType ( ) ) {
676+ return true ;
677+ }
678+ }
679+ if ( inst . OpCode == OpCodes . Call ) {
680+ var resolvedCallee = ( ( MethodReference ) inst . Operand ) . TryResolve ( ) ;
681+ if ( resolvedCallee is not null
682+ && resolvedCallee . IsStatic
683+ && ! resolvedCallee . IsConstructor
684+ && resolvedCallee . ReturnType . FullName == source . MainModule . TypeSystem . Void . FullName ) {
685+ if ( visited . Add ( resolvedCallee . GetIdentifier ( ) ) ) {
686+ stack . Push ( resolvedCallee ) ;
687+ }
688+ }
689+ }
690+ }
691+ }
692+ return false ;
693+ }
694+
695+ foreach ( var inst in method . Body . Instructions ) {
696+
697+ if ( inst . OpCode != OpCodes . Call ) {
698+ continue ;
699+ }
700+
701+ var resolvedCallee = ( ( MethodReference ) inst . Operand ) . TryResolve ( ) ;
702+ if ( resolvedCallee is null
703+ || ! resolvedCallee . IsStatic
704+ || resolvedCallee . IsConstructor
705+ || resolvedCallee . ReturnType . FullName != source . MainModule . TypeSystem . Void . FullName ) {
706+ continue ;
707+ }
708+
709+ if ( ! UsedStaticField ( resolvedCallee ) ) {
710+ continue ;
711+ }
712+
713+
714+ HashSet < Instruction > tmp = [ ] ;
715+ ExtractSources ( this , method , tmp , inst ) ;
716+
717+ if ( IsExtractableStaticPart ( source , tmp ) ) {
718+ foreach ( var staticInst in tmp ) {
719+ extractedStaticInsts . Add ( staticInst ) ;
720+ }
721+ }
722+ }
723+
655724 foreach ( var loopBlock in loopBlocks . Values ) {
656725 foreach ( var fieldModification in loopBlock . FilteredLoopBody ) {
657726 if ( ! source . InitialStaticFields . TryGetValue ( fieldModification . Key , out var initFieldDef ) ) {
@@ -921,7 +990,11 @@ static Instruction CloneAndUpdateMap(Dictionary<Instruction, Instruction> instMa
921990 }
922991 }
923992
924- foreach ( var key in myCalingMethods . Keys . ToArray ( ) ) {
993+ foreach ( var calleeKV in myCalingMethods . ToArray ( ) ) {
994+ var key = calleeKV . Key ;
995+ if ( calleeKV . Value . Parameters . Count != 0 ) {
996+ myCalingMethods . Remove ( key ) ;
997+ }
925998 if ( multipleCalls . TryGetValue ( key , out var multipleCallCount ) && multipleCallCount != 1 ) {
926999 myCalingMethods . Remove ( key ) ;
9271000 }
@@ -1042,6 +1115,51 @@ private bool IsExtractableStaticPart(FilterArgumentSource source, FieldDefinitio
10421115 }
10431116 return true ;
10441117 }
1118+ private bool IsExtractableStaticPart ( FilterArgumentSource source , IEnumerable < Instruction > instructions ) {
1119+ foreach ( var inst in instructions ) {
1120+ switch ( inst . OpCode . Code ) {
1121+ case Code . Ldsfld :
1122+ case Code . Ldsflda :
1123+ case Code . Stsfld : {
1124+ var fieldRef = ( FieldReference ) inst . Operand ;
1125+ var id = fieldRef . GetIdentifier ( ) ;
1126+ if ( source . ModifiedStaticFields . ContainsKey ( id ) ) {
1127+ return false ;
1128+ }
1129+ }
1130+ break ;
1131+ case Code . Call :
1132+ case Code . Callvirt :
1133+ case Code . Newobj : {
1134+ var methodRef = ( MethodReference ) inst . Operand ;
1135+ var methodDef = methodRef . TryResolve ( ) ;
1136+ if ( methodDef is null ) {
1137+ break ;
1138+ }
1139+ if ( this . CheckUsedContextBoundField ( source . ModifiedStaticFields , methodDef ) ) {
1140+ return false ;
1141+ }
1142+ }
1143+ break ;
1144+ }
1145+ }
1146+ foreach ( var inst in instructions ) {
1147+ switch ( inst . OpCode . Code ) {
1148+ case Code . Ldarg_0 :
1149+ case Code . Ldarg_1 :
1150+ case Code . Ldarg_2 :
1151+ case Code . Ldarg_3 :
1152+ case Code . Ldarg_S :
1153+ case Code . Ldarg :
1154+ case Code . Ldarga_S :
1155+ case Code . Ldarga :
1156+ case Code . Starg_S :
1157+ case Code . Starg :
1158+ return false ;
1159+ }
1160+ }
1161+ return true ;
1162+ }
10451163 /// <summary>
10461164 ///
10471165 /// </summary>
0 commit comments