@@ -258,72 +258,77 @@ private void EmitRunnableCore()
258258
259259 private void EmitFields ( )
260260 {
261- /*
262- private unsafe struct FieldsContainer
263- {
264- }
265- */
266- var fieldsContainerBuilder = runnableBuilder . DefineNestedType (
267- "FieldsContainer" ,
268- TypeAttributes . NestedPrivate | TypeAttributes . AutoLayout | TypeAttributes . Sealed | TypeAttributes . BeforeFieldInit ,
269- typeof ( ValueType ) ) ;
270- nestedTypeBuilders . Add ( fieldsContainerBuilder ) ;
271-
272- // Define arg fields
273- foreach ( var parameter in Descriptor . WorkloadMethod . GetParameters ( ) )
261+ var parameters = Descriptor . WorkloadMethod . GetParameters ( ) ;
262+ if ( parameters . Length + GetExtraFieldsCount ( ) > 0 )
274263 {
275- var argValue = benchmark . BenchmarkCase . Parameters . GetArgument ( parameter . Name ! ) ;
276- var parameterType = parameter . ParameterType ;
277-
278- Type argLocalsType ;
279- Type argFieldType ;
280- MethodInfo ? opConversion = null ;
281- if ( parameterType . IsByRef )
282- {
283- argLocalsType = parameterType ;
284- argFieldType = argLocalsType . GetElementType ( )
285- ?? throw new InvalidOperationException ( $ "Bug: cannot get field type from { argLocalsType } ") ;
286- }
287- else if ( parameterType . IsByRefLike ( ) && argValue . Value != null )
288- {
289- argLocalsType = parameterType ;
290-
291- // Use conversion on load; store passed value
292- var passedArgType = argValue . Value . GetType ( ) ;
293- opConversion = GetImplicitConversionOpFromTo ( passedArgType , argLocalsType ) ??
294- throw new InvalidOperationException ( $ "Bug: No conversion from { passedArgType } to { argLocalsType } .") ;
295- argFieldType = passedArgType ;
296- }
297- else
264+ /*
265+ private unsafe struct FieldsContainer
266+ {
267+ }
268+ */
269+ var fieldsContainerBuilder = runnableBuilder . DefineNestedType (
270+ "FieldsContainer" ,
271+ TypeAttributes . NestedPrivate | TypeAttributes . AutoLayout | TypeAttributes . Sealed | TypeAttributes . BeforeFieldInit ,
272+ typeof ( ValueType ) ) ;
273+ nestedTypeBuilders . Add ( fieldsContainerBuilder ) ;
274+
275+ // Define arg fields
276+ foreach ( var parameter in parameters )
298277 {
299- // No conversion; load ref to arg field;
300- argLocalsType = parameterType ;
301- argFieldType = parameterType ;
278+ var argValue = benchmark . BenchmarkCase . Parameters . GetArgument ( parameter . Name ! ) ;
279+ var parameterType = parameter . ParameterType ;
280+
281+ Type argLocalsType ;
282+ Type argFieldType ;
283+ MethodInfo ? opConversion = null ;
284+ if ( parameterType . IsByRef )
285+ {
286+ argLocalsType = parameterType ;
287+ argFieldType = argLocalsType . GetElementType ( )
288+ ?? throw new InvalidOperationException ( $ "Bug: cannot get field type from { argLocalsType } ") ;
289+ }
290+ else if ( parameterType . IsByRefLike ( ) && argValue . Value != null )
291+ {
292+ argLocalsType = parameterType ;
293+
294+ // Use conversion on load; store passed value
295+ var passedArgType = argValue . Value . GetType ( ) ;
296+ opConversion = GetImplicitConversionOpFromTo ( passedArgType , argLocalsType )
297+ ?? throw new InvalidOperationException ( $ "Bug: No conversion from { passedArgType } to { argLocalsType } .") ;
298+ argFieldType = passedArgType ;
299+ }
300+ else
301+ {
302+ // No conversion; load ref to arg field;
303+ argLocalsType = parameterType ;
304+ argFieldType = parameterType ;
305+ }
306+
307+ if ( argFieldType . IsByRefLike ( ) )
308+ throw new NotSupportedException ( $ "Passing ref readonly structs by ref is not supported (cannot store { argFieldType } as a class field).") ;
309+
310+ var argField = fieldsContainerBuilder . DefineField (
311+ ArgFieldPrefix + parameter . Position ,
312+ argFieldType ,
313+ FieldAttributes . Public ) ;
314+
315+ argFields . Add ( new ( argField , argLocalsType , opConversion ) ) ;
302316 }
303317
304- if ( argFieldType . IsByRefLike ( ) )
305- throw new NotSupportedException (
306- $ "Passing ref readonly structs by ref is not supported (cannot store { argFieldType } as a class field).") ;
318+ EmitExtraFields ( fieldsContainerBuilder ) ;
307319
308- var argField = fieldsContainerBuilder . DefineField (
309- ArgFieldPrefix + parameter . Position ,
310- argFieldType ,
311- FieldAttributes . Public ) ;
312-
313- argFields . Add ( new ( argField , argLocalsType , opConversion ) ) ;
320+ // private FieldsContainer __fieldsContainer;
321+ fieldsContainerField = runnableBuilder . DefineField (
322+ FieldsContainerName ,
323+ fieldsContainerBuilder ,
324+ FieldAttributes . Private ) ;
314325 }
315326
316- EmitExtraFields ( fieldsContainerBuilder ) ;
317-
318- // private FieldsContainer __fieldsContainer;
319- fieldsContainerField = runnableBuilder . DefineField (
320- FieldsContainerName ,
321- fieldsContainerBuilder ,
322- FieldAttributes . Private ) ;
323-
324327 notElevenField = runnableBuilder . DefineField ( NotElevenFieldName , typeof ( int ) , FieldAttributes . Public ) ;
325328 }
326329
330+ protected virtual int GetExtraFieldsCount ( ) => 0 ;
331+
327332 protected virtual void EmitExtraFields ( TypeBuilder fieldsContainerBuilder ) { }
328333
329334 private void EmitCtor ( )
0 commit comments