@@ -1113,7 +1113,7 @@ bool CLR_RT_ExecutionEngine::SpawnGenericTypeStaticConstructorsHelper(
11131113 record->m_flags &= ~CLR_RT_GenericCctorExecutionRecord::c_Scheduled;
11141114 }
11151115
1116- // No more generic type .cctors for this assembly - set flag
1116+ // no more generic type .cctors for this assembly - set flag
11171117 assembly->flags |= CLR_RT_Assembly::StaticGenericConstructorsExecuted;
11181118 return false ;
11191119}
@@ -1164,69 +1164,86 @@ void CLR_RT_ExecutionEngine::SpawnStaticConstructor(CLR_RT_Thread *&pCctorThread
11641164 }
11651165 }
11661166
1167- // first, find the AppDomainAssembly to run. (what about appdomains!!!)
1168- NANOCLR_FOREACH_ASSEMBLY (g_CLR_RT_TypeSystem)
1167+ // keep iterating until no more static constructors can be spawned
1168+ // note that multiple passes may be needed to satisfy all dependencies
1169+ bool anySpawned;
1170+
1171+ do
11691172 {
1170- // Check if regular static constructors need to be executed
1171- if ((pASSM->flags & CLR_RT_Assembly::StaticConstructorsExecuted) == 0 )
1172- {
1173- CLR_RT_MethodDef_Index index;
1174- index.Set (pASSM->assemblyIndex , 0 );
1175- bool dependenciesSatisfied = true ;
1173+ anySpawned = false ;
11761174
1177- // Check that all dependent assemblies have had regular static constructors run
1178- CLR_RT_AssemblyRef_CrossReference *ar = pASSM->crossReferenceAssemblyRef ;
1179- for (int i = 0 ; i < pASSM->tablesSize [TBL_AssemblyRef]; i++, ar++)
1175+ NANOCLR_FOREACH_ASSEMBLY (g_CLR_RT_TypeSystem)
1176+ {
1177+ // Check if regular static constructors need to be executed
1178+ if ((pASSM->flags & CLR_RT_Assembly::StaticConstructorsExecuted) == 0 )
11801179 {
1181- if ((ar->target ->flags & CLR_RT_Assembly::StaticConstructorsExecuted) == 0 )
1180+ CLR_RT_MethodDef_Index index;
1181+ index.Set (pASSM->assemblyIndex , 0 );
1182+ bool dependenciesSatisfied = true ;
1183+
1184+ // Check that all dependent assemblies have had regular static constructors run
1185+ CLR_RT_AssemblyRef_CrossReference *ar = pASSM->crossReferenceAssemblyRef ;
1186+ for (int i = 0 ; i < pASSM->tablesSize [TBL_AssemblyRef]; i++, ar++)
11821187 {
1183- dependenciesSatisfied = false ;
1184- break ;
1188+ if ((ar->target ->flags & CLR_RT_Assembly::StaticConstructorsExecuted) == 0 )
1189+ {
1190+ dependenciesSatisfied = false ;
1191+ break ;
1192+ }
11851193 }
1186- }
11871194
1188- if (dependenciesSatisfied)
1189- {
1190- // Run regular static constructors for this assembly
1191- if (SpawnStaticConstructorHelper (pASSM, index))
1195+ if (dependenciesSatisfied)
11921196 {
1193- return ;
1197+ if (SpawnStaticConstructorHelper (pASSM, index))
1198+ {
1199+ return ;
1200+ }
1201+
1202+ // returned false, meaning it set the flag and there are no more cctors for this assembly.
1203+ // flag that progress was made and we should re-iterate
1204+ anySpawned = true ;
11941205 }
1195- }
1196- }
11971206
1198- // Check if generic type static constructors need to be executed
1199- if ((pASSM->flags & CLR_RT_Assembly::StaticGenericConstructorsExecuted) == 0 )
1200- {
1201- bool dependenciesSatisfied = true ;
1207+ // if there are dependencies not satisfied, just continue to next assembly
1208+ continue ;
1209+ }
12021210
1203- // Check that all dependent assemblies have had regular static constructors run
1204- CLR_RT_AssemblyRef_CrossReference *ar = pASSM->crossReferenceAssemblyRef ;
1205- for (int i = 0 ; i < pASSM->tablesSize [TBL_AssemblyRef]; i++, ar++)
1211+ // Check if generic type static constructors need to be executed
1212+ if ((pASSM->flags & CLR_RT_Assembly::StaticGenericConstructorsExecuted) == 0 )
12061213 {
1207- if ((ar->target ->flags & CLR_RT_Assembly::StaticConstructorsExecuted) == 0 )
1214+ bool dependenciesSatisfied = true ;
1215+
1216+ // Check that all dependent assemblies have had regular static constructors run
1217+ CLR_RT_AssemblyRef_CrossReference *ar = pASSM->crossReferenceAssemblyRef ;
1218+ for (int i = 0 ; i < pASSM->tablesSize [TBL_AssemblyRef]; i++, ar++)
12081219 {
1209- dependenciesSatisfied = false ;
1210- break ;
1220+ if ((ar->target ->flags & CLR_RT_Assembly::StaticConstructorsExecuted) == 0 )
1221+ {
1222+ dependenciesSatisfied = false ;
1223+ break ;
1224+ }
12111225 }
1212- }
1213-
1214- if (dependenciesSatisfied)
1215- {
1216- // Run generic type static constructors for this assembly (starting from index 0)
1217- CLR_RT_TypeSpec_Index startIndex;
1218- startIndex.Set (pASSM->assemblyIndex , 0 );
12191226
1220- if (SpawnGenericTypeStaticConstructorsHelper (pASSM, startIndex) )
1227+ if (dependenciesSatisfied )
12211228 {
1222- return ;
1229+ CLR_RT_TypeSpec_Index startIndex;
1230+ startIndex.Set (pASSM->assemblyIndex , 0 );
1231+
1232+ if (SpawnGenericTypeStaticConstructorsHelper (pASSM, startIndex))
1233+ {
1234+ return ;
1235+ }
1236+
1237+ // returned false, meaning it set the flag and there are no more generic cctors for this assembly.
1238+ // flag that progress was made and we should re-iterate
1239+ anySpawned = true ;
12231240 }
12241241 }
12251242 }
1226- }
1227- NANOCLR_FOREACH_ASSEMBLY_END ();
1243+ NANOCLR_FOREACH_ASSEMBLY_END ();
1244+
1245+ } while (anySpawned);
12281246
1229- // no more static constructors needed...
12301247 pCctorThread->DestroyInstance ();
12311248}
12321249#endif // NANOCLR_APPDOMAINS
0 commit comments