@@ -37,6 +37,9 @@ THE SOFTWARE.
3737#if LIGHT_EXPRESSION || ! NET45
3838#define SUPPORTS_ARGUMENT_PROVIDER
3939#endif
40+ #if ! NETSTANDARD2_0
41+ #define SUPPORTS_EMITCALL
42+ #endif
4043#if LIGHT_EXPRESSION
4144using static FastExpressionCompiler . LightExpression . Expression ;
4245using PE = FastExpressionCompiler . LightExpression . ParameterExpression ;
@@ -2077,11 +2080,11 @@ private static bool TryEmitIndex(IndexExpression indexExpr, IReadOnlyList<PE> p
20772080 if ( indexerPropGetter != null )
20782081 return EmitMethodCall ( il , indexerPropGetter ) ;
20792082
2080- if ( indexArgCount == 1 ) // one dimensional array
2083+ if ( indexArgCount == 1 ) // one- dimensional array
20812084 return TryEmitArrayIndex ( indexExpr . Type , il , parent , ref closure ) ;
20822085
2083- // multi dimensional array
2084- return EmitMethodCall ( il , indexExpr . Object ? . Type . FindMethod ( "Get" ) ) ;
2086+ indexerPropGetter = indexExpr . Object ? . Type . FindMethod ( "Get" ) ; // multi- dimensional array
2087+ return indexerPropGetter != null && EmitMethodCall ( il , indexerPropGetter ) ;
20852088 }
20862089
20872090#if LIGHT_EXPRESSION
@@ -3313,11 +3316,7 @@ private static bool EmitMemberAssign(ILGenerator il, MemberInfo member)
33133316 if ( member is PropertyInfo prop )
33143317 {
33153318 var method = prop . DeclaringType . FindPropertySetMethod ( prop . Name ) ;
3316- if ( method == null )
3317- return false ;
3318-
3319- il . Emit ( method . IsVirtual ? OpCodes . Callvirt : OpCodes . Call , method ) ;
3320- return true ;
3319+ return method != null && EmitMethodCall ( il , method ) ;
33213320 }
33223321 if ( member is FieldInfo field )
33233322 {
@@ -3400,7 +3399,7 @@ private static bool TryEmitListInit(ListInitExpression expr, IReadOnlyList<PE> p
34003399 return false ;
34013400
34023401 if ( ! exprType . IsValueType )
3403- il . Emit ( method . IsVirtual ? OpCodes . Callvirt : OpCodes . Call , method ) ;
3402+ EmitMethodCall ( il , method ) ;
34043403 else if ( ! method . IsVirtual ) // #251 - no need for constrain or virtual call because it is already by-ref
34053404 il . Emit ( OpCodes . Call , method ) ;
34063405 else if ( method . DeclaringType == exprType )
@@ -3837,8 +3836,8 @@ private static bool TryEmitIndexAssign(IndexExpression indexExpr, Type instType,
38373836 return true ;
38383837 }
38393838
3840- // multi dimensional array
3841- return EmitMethodCall ( il , instType ? . FindMethod ( "Set" ) ) ;
3839+ var setter = instType ? . FindMethod ( "Set" ) ;
3840+ return setter != null && EmitMethodCall ( il , setter ) ; // multi dimensional array
38423841 }
38433842
38443843#if LIGHT_EXPRESSION
@@ -3883,7 +3882,7 @@ private static bool TryEmitMethodCall(Expression expr, IReadOnlyList<PE> paramE
38833882 }
38843883
38853884 if ( ! objIsValueType )
3886- il . Emit ( method . IsVirtual ? OpCodes . Callvirt : OpCodes . Call , method ) ;
3885+ EmitMethodCall ( il , method ) ;
38873886 else if ( ! method . IsVirtual || objExpr is ParameterExpression p && p . IsByRef )
38883887 il . Emit ( OpCodes . Call , method ) ;
38893888 else if ( method . DeclaringType == objExpr . Type )
@@ -4496,7 +4495,7 @@ private static bool TryEmitArithmetic(BinaryExpression expr, ExpressionType expr
44964495 if ( ! TryEmitArithmeticOperation ( expr , exprNodeType , exprType , il ) )
44974496 return false ;
44984497
4499- if ( leftIsNullable || rightIsNullable )
4498+ if ( leftIsNullable || rightIsNullable ) // todo: @clarify that the code emitted is correct
45004499 {
45014500 var valueLabel = il . DefineLabel ( ) ;
45024501 il . Emit ( OpCodes . Br , valueLabel ) ;
@@ -4581,10 +4580,7 @@ var methodName
45814580 }
45824581 }
45834582
4584- if ( method == null )
4585- return false ;
4586- il . Emit ( method . IsVirtual ? OpCodes . Callvirt : OpCodes . Call , method ) ;
4587- return true ;
4583+ return method != null && EmitMethodCall ( il , method ) ;
45884584 }
45894585 }
45904586
@@ -4855,15 +4851,14 @@ private static Expression TryReduceCondition(Expression testExpr)
48554851 return testExpr ;
48564852 }
48574853
4858- private static bool EmitMethodCall ( ILGenerator il , MethodInfo method , ParentFlags parent = ParentFlags . Empty )
4854+ [ MethodImpl ( ( MethodImplOptions ) 256 ) ]
4855+ private static bool EmitMethodCall ( ILGenerator il , MethodInfo method )
48594856 {
4860- if ( method == null )
4861- return false ;
4862-
4857+ # if SUPPORTS_EMITCALL
4858+ il . EmitCall ( method . IsVirtual ? OpCodes . Callvirt : OpCodes . Call , method , null ) ;
4859+ #else
48634860 il . Emit ( method . IsVirtual ? OpCodes . Callvirt : OpCodes . Call , method ) ;
4864-
4865- if ( ( parent & ParentFlags . IgnoreResult ) != 0 && method . ReturnType != typeof ( void ) )
4866- il . Emit ( OpCodes . Pop ) ;
4861+ #endif
48674862 return true ;
48684863 }
48694864
0 commit comments