@@ -32,13 +32,16 @@ internal static string Generate(BuildPartition buildPartition, CodeGenBenchmarkR
3232 {
3333 var benchmark = buildInfo . BenchmarkCase ;
3434
35- string benchmarkTypeCode = GetDeclarationsProvider ( benchmark )
35+ var declarationsProvider = GetDeclarationsProvider ( benchmark ) ;
36+ var extraFields = declarationsProvider . GetExtraFields ( ) ;
37+
38+ string benchmarkTypeCode = declarationsProvider
3639 . ReplaceTemplate ( new SmartStringBuilder ( ResourceHelper . LoadTemplate ( "BenchmarkType.txt" ) ) )
3740 . Replace ( "$ID$" , buildInfo . Id . ToString ( ) )
3841 . Replace ( "$JobSetDefinition$" , GetJobsSetDefinition ( benchmark ) )
3942 . Replace ( "$ParamsContent$" , GetParamsContent ( benchmark ) )
4043 . Replace ( "$ArgumentsDefinition$" , GetArgumentsDefinition ( benchmark ) )
41- . Replace ( "$DeclareArgumentFields $" , GetDeclareArgumentFields ( benchmark ) )
44+ . Replace ( "$DeclareFieldsContainer $" , GetDeclareFieldsContainer ( benchmark , buildInfo . Id , extraFields ) )
4245 . Replace ( "$InitializeArgumentFields$" , GetInitializeArgumentFields ( benchmark ) )
4346 . Replace ( "$EngineFactoryType$" , GetEngineFactoryTypeName ( benchmark ) )
4447 . Replace ( "$RunExtraIteration$" , buildInfo . Config . HasExtraIterationDiagnoser ( benchmark ) ? "true" : "false" )
@@ -144,11 +147,48 @@ private static string GetArgumentsDefinition(BenchmarkCase benchmarkCase)
144147 benchmarkCase . Descriptor . WorkloadMethod . GetParameters ( )
145148 . Select ( ( parameter , index ) => $ "{ GetParameterModifier ( parameter ) } { parameter . ParameterType . GetCorrectCSharpTypeName ( ) } arg{ index } ") ) ;
146149
147- private static string GetDeclareArgumentFields ( BenchmarkCase benchmarkCase )
148- => string . Join (
149- Environment . NewLine ,
150- benchmarkCase . Descriptor . WorkloadMethod . GetParameters ( )
151- . Select ( ( parameter , index ) => $ "public { GetFieldType ( parameter . ParameterType , benchmarkCase . Parameters . GetArgument ( parameter . Name ! ) ) . GetCorrectCSharpTypeName ( ) } __argField{ index } ;") ) ;
150+ private static string GetDeclareFieldsContainer ( BenchmarkCase benchmarkCase , BenchmarkId benchmarkId , string [ ] extraFields )
151+ {
152+ var fields = benchmarkCase . Descriptor . WorkloadMethod . GetParameters ( )
153+ . Select ( ( parameter , index ) => $ "public { GetFieldType ( parameter . ParameterType , benchmarkCase . Parameters . GetArgument ( parameter . Name ! ) ) . GetCorrectCSharpTypeName ( ) } __argField{ index } ;")
154+ . Concat ( extraFields )
155+ . ToArray ( ) ;
156+
157+ // Prevent CS0169
158+ if ( fields . Length == 0 )
159+ {
160+ return string . Empty ;
161+ }
162+
163+ // Wrapper struct is necessary because of error CS4004: Cannot await in an unsafe context
164+ var sb = new StringBuilder ( ) ;
165+ sb . AppendLine ( """
166+ [global::System.Runtime.InteropServices.StructLayout(global::System.Runtime.InteropServices.LayoutKind.Auto)]
167+ private unsafe struct FieldsContainer
168+ {
169+ """ ) ;
170+ foreach ( var field in fields )
171+ {
172+ sb . AppendLine ( $ " { field } ") ;
173+ }
174+ sb . AppendLine ( " }" ) ;
175+ sb . AppendLine ( ) ;
176+ sb . AppendLine ( $ " private global::BenchmarkDotNet.Autogenerated.Runnable_{ benchmarkId . Value } .FieldsContainer __fieldsContainer;") ;
177+ return sb . ToString ( ) ;
178+ }
179+
180+ /*
181+
182+ [global::System.Runtime.InteropServices.StructLayout(global::System.Runtime.InteropServices.LayoutKind.Auto)]
183+ private unsafe struct FieldsContainer
184+ {
185+ $DeclareArgumentFields$
186+ $ExtraFields$
187+ }
188+
189+ private global::BenchmarkDotNet.Autogenerated.Runnable_$ID$.FieldsContainer __fieldsContainer;
190+
191+ */
152192
153193 private static string GetInitializeArgumentFields ( BenchmarkCase benchmarkCase )
154194 => string . Join (
0 commit comments