11using System ;
2+ using System . Linq ;
23using System . Reflection ;
34using System . Runtime . CompilerServices ;
45using System . Threading . Tasks ;
910namespace BenchmarkDotNet . Toolchains . InProcess . NoEmit
1011{
1112 /// <summary>Helper class that creates <see cref="BenchmarkAction"/> instances. </summary>
12- public static partial class BenchmarkActionFactory
13+ internal static partial class BenchmarkActionFactory
1314 {
1415 /// <summary>
1516 /// Dispatch method that creates <see cref="BenchmarkAction"/> using
1617 /// <paramref name="targetMethod"/> or <paramref name="fallbackIdleSignature"/> to find correct implementation.
1718 /// Either <paramref name="targetMethod"/> or <paramref name="fallbackIdleSignature"/> should be not <c>null</c>.
1819 /// </summary>
19- private static BenchmarkAction CreateCore (
20- object instance ,
21- MethodInfo ? targetMethod ,
22- MethodInfo ? fallbackIdleSignature ,
23- int unrollFactor )
20+ private static BenchmarkAction CreateCore ( object instance , MethodInfo ? targetMethod , MethodInfo ? fallbackIdleSignature , int unrollFactor )
2421 {
2522 PrepareInstanceAndResultType ( instance , targetMethod , fallbackIdleSignature , out var resultInstance , out var resultType ) ;
2623
2724 if ( resultType == typeof ( void ) )
2825 return new BenchmarkActionVoid ( resultInstance , targetMethod , unrollFactor ) ;
2926
27+ if ( resultType == typeof ( void * ) )
28+ return new BenchmarkActionVoidPointer ( resultInstance , targetMethod , unrollFactor ) ;
29+
30+ if ( resultType . IsByRef )
31+ {
32+ var returnParameter = targetMethod ? . ReturnParameter ?? fallbackIdleSignature . ReturnParameter ;
33+ // IsReadOnlyAttribute is not part of netstandard2.0, so we need to check the attribute name as usual.
34+ if ( returnParameter . GetCustomAttributes ( ) . Any ( attribute => attribute . GetType ( ) . FullName == "System.Runtime.CompilerServices.IsReadOnlyAttribute" ) )
35+ return Create (
36+ typeof ( BenchmarkActionByRefReadonly < > ) . MakeGenericType ( resultType . GetElementType ( ) ) ,
37+ resultInstance ,
38+ targetMethod ,
39+ unrollFactor ) ;
40+
41+ return Create (
42+ typeof ( BenchmarkActionByRef < > ) . MakeGenericType ( resultType . GetElementType ( ) ) ,
43+ resultInstance ,
44+ targetMethod ,
45+ unrollFactor ) ;
46+ }
47+
3048 if ( resultType == typeof ( Task ) )
3149 return new BenchmarkActionTask ( resultInstance , targetMethod , unrollFactor ) ;
3250
51+ if ( resultType == typeof ( ValueTask ) )
52+ return new BenchmarkActionValueTask ( resultInstance , targetMethod , unrollFactor ) ;
53+
3354 if ( resultType . GetTypeInfo ( ) . IsGenericType )
3455 {
3556 var genericType = resultType . GetGenericTypeDefinition ( ) ;
@@ -49,10 +70,6 @@ private static BenchmarkAction CreateCore(
4970 unrollFactor ) ;
5071 }
5172
52- if ( targetMethod == null && resultType . GetTypeInfo ( ) . IsValueType )
53- // for Idle: we return int because creating bigger ValueType could take longer than benchmarked method itself.
54- resultType = typeof ( int ) ;
55-
5673 return Create (
5774 typeof ( BenchmarkAction < > ) . MakeGenericType ( resultType ) ,
5875 resultInstance ,
@@ -86,6 +103,10 @@ private static void PrepareInstanceAndResultType(
86103 if ( isUsingAsyncKeyword )
87104 throw new NotSupportedException ( "Async void is not supported by design." ) ;
88105 }
106+ else if ( resultType . IsPointer && resultType != typeof ( void * ) )
107+ {
108+ throw new NotSupportedException ( "InProcessNoEmitToolchain only supports void* return, not T*" ) ;
109+ }
89110 }
90111
91112 /// <summary>Helper to enforce .ctor signature.</summary>
@@ -109,7 +130,7 @@ public static BenchmarkAction CreateWorkload(Descriptor descriptor, object insta
109130 /// <param name="unrollFactor">Unroll factor.</param>
110131 /// <returns>Idle benchmark action.</returns>
111132 public static BenchmarkAction CreateOverhead ( Descriptor descriptor , object instance , int unrollFactor ) =>
112- CreateCore ( instance , null , descriptor . WorkloadMethod , unrollFactor ) ;
133+ CreateCore ( instance , null , FallbackSignature , unrollFactor ) ;
113134
114135 /// <summary>Creates global setup benchmark action.</summary>
115136 /// <param name="descriptor">Descriptor info.</param>
0 commit comments