Skip to content

Commit 9a1e6f9

Browse files
committed
using the PropertyInfo.GetMethod and SetMethod instead of my own code
1 parent 28939f0 commit 9a1e6f9

File tree

1 file changed

+26
-70
lines changed

1 file changed

+26
-70
lines changed

src/FastExpressionCompiler/FastExpressionCompiler.cs

Lines changed: 26 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,9 @@ public enum NotSupported
9494
/// <summary>MemberInit ListBinding is not supported</summary>
9595
MemberInit_ListBinding,
9696
/// <summary>Goto of the Return kind from the TryCatch is not supported</summary>
97-
Try_GotoReturnToTheFollowupLabel
97+
Try_GotoReturnToTheFollowupLabel,
98+
/// <summary>Not supported assignment target</summary>
99+
Assign_Target
98100
}
99101

100102
/// <summary>FEC Not Supported exception</summary>
@@ -104,6 +106,8 @@ public sealed class NotSupportedExpressionException : InvalidOperationException
104106
public readonly NotSupported Reason;
105107
/// <summary>Constructor</summary>
106108
public NotSupportedExpressionException(NotSupported reason) : base(reason.ToString()) => Reason = reason;
109+
/// <summary>Constructor</summary>
110+
public NotSupportedExpressionException(NotSupported reason, string message) : base(reason + ": " + message) => Reason = reason;
107111
}
108112

109113
/// <summary>The interface is implemented by the compiled delegate Target if `CompilerFlags.EnableDelegateDebugInfo` is set.</summary>
@@ -2130,7 +2134,7 @@ private static bool TryEmitIndex(IndexExpression indexExpr, IReadOnlyList<PE> p
21302134
var indexerProp = indexExpr.Indexer;
21312135
MethodInfo indexerPropGetter = null;
21322136
if (indexerProp != null)
2133-
indexerPropGetter = indexerProp.DeclaringType.FindPropertyGetMethod(indexerProp.Name);
2137+
indexerPropGetter = indexerProp.GetMethod;
21342138

21352139
var p = parent | ParentFlags.IndexAccess;
21362140
if (indexerPropGetter == null)
@@ -2148,13 +2152,13 @@ private static bool TryEmitIndex(IndexExpression indexExpr, IReadOnlyList<PE> p
21482152
}
21492153

21502154
if (indexerPropGetter != null)
2151-
return EmitMethodCallOrVirtCall(il, indexerPropGetter);
2155+
return EmitMethodCallOrVirtualCall(il, indexerPropGetter);
21522156

21532157
if (indexArgCount == 1) // one-dimensional array
21542158
return TryEmitArrayIndex(indexExpr.Type, il, parent, ref closure);
21552159

21562160
indexerPropGetter = indexExpr.Object?.Type.FindMethod("Get"); // multi-dimensional array
2157-
return indexerPropGetter != null && EmitMethodCallOrVirtCall(il, indexerPropGetter);
2161+
return indexerPropGetter != null && EmitMethodCallOrVirtualCall(il, indexerPropGetter);
21582162
}
21592163

21602164
#if LIGHT_EXPRESSION
@@ -2747,7 +2751,7 @@ private static bool TryEmitConvert(UnaryExpression expr, IReadOnlyList<PE> param
27472751
if (!TryEmit(opExpr, paramExprs, il, ref closure, setup,
27482752
parent & ~ParentFlags.IgnoreResult | ParentFlags.InstanceCall, -1))
27492753
return false;
2750-
return EmitMethodCallOrVirtCall(il, method);
2754+
return EmitMethodCallOrVirtualCall(il, method);
27512755
}
27522756

27532757
var sourceType = opExpr.Type;
@@ -3419,8 +3423,8 @@ private static bool EmitMemberAssign(ILGenerator il, MemberInfo member)
34193423
{
34203424
if (member is PropertyInfo prop)
34213425
{
3422-
var method = prop.DeclaringType.FindPropertySetMethod(prop.Name);
3423-
return method != null && EmitMethodCallOrVirtCall(il, method);
3426+
var method = prop.SetMethod;
3427+
return method != null && EmitMethodCallOrVirtualCall(il, method);
34243428
}
34253429
if (member is FieldInfo field)
34263430
{
@@ -3503,7 +3507,7 @@ private static bool TryEmitListInit(ListInitExpression expr, IReadOnlyList<PE> p
35033507
}
35043508

35053509
if (!exprType.IsValueType)
3506-
EmitMethodCallOrVirtCall(il, method);
3510+
EmitMethodCallOrVirtualCall(il, method);
35073511
else if (!method.IsVirtual) // #251 - no need for constrain or virtual call because it is already by-ref
35083512
EmitMethodCall(il, method);
35093513
else if (method.DeclaringType == exprType)
@@ -3869,7 +3873,9 @@ private static bool TryEmitAssign(BinaryExpression expr, IReadOnlyList<PE> param
38693873
EmitLoadLocalVariable(il, varIndex);
38703874
return true;
38713875

3872-
default: // todo: not yet support assignment targets
3876+
default: // todo: @feature not yet support assignment targets
3877+
if ((setup & CompilerFlags.ThrowOnNotSupportedExpression) != 0)
3878+
throw new NotSupportedExpressionException(NotSupported.Assign_Target, $"Assignment target `{nodeType}` is not supported");
38733879
return false;
38743880
}
38753881
}
@@ -3912,7 +3918,7 @@ private static bool TryEmitIndexAssign(IndexExpression indexExpr, Type instType,
39123918
}
39133919

39143920
var setter = instType?.FindMethod("Set");
3915-
return setter != null && EmitMethodCallOrVirtCall(il, setter); // multi dimensional array
3921+
return setter != null && EmitMethodCallOrVirtualCall(il, setter); // multi dimensional array
39163922
}
39173923

39183924
#if LIGHT_EXPRESSION
@@ -3957,7 +3963,7 @@ private static bool TryEmitMethodCall(Expression expr, IReadOnlyList<PE> paramE
39573963
}
39583964

39593965
if (!objIsValueType)
3960-
EmitMethodCallOrVirtCall(il, method);
3966+
EmitMethodCallOrVirtualCall(il, method);
39613967
else if (!method.IsVirtual || objExpr is ParameterExpression p && p.IsByRef)
39623968
EmitMethodCall(il, method);
39633969
else if (method.DeclaringType == objExpr.Type)
@@ -4006,11 +4012,7 @@ private static bool TryEmitMemberAccess(MemberExpression expr, IReadOnlyList<PE>
40064012
}
40074013

40084014
closure.LastEmitIsAddress = false;
4009-
var propGetter = prop.DeclaringType.FindPropertyGetMethod(prop.Name);
4010-
if (propGetter == null)
4011-
return false;
4012-
4013-
il.Emit(propGetter.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, propGetter);
4015+
EmitMethodCallOrVirtualCall(il, prop.GetMethod);
40144016
return true;
40154017
}
40164018

@@ -4674,7 +4676,7 @@ var methodName
46744676
}
46754677
}
46764678

4677-
return method != null && EmitMethodCallOrVirtCall(il, method);
4679+
return method != null && EmitMethodCallOrVirtualCall(il, method);
46784680
}
46794681
}
46804682

@@ -4953,7 +4955,7 @@ private static Expression TryReduceCondition(Expression testExpr)
49534955

49544956
// get the advantage of the optimized specialized EmitCall method
49554957
[MethodImpl((MethodImplOptions)256)]
4956-
private static bool EmitMethodCallOrVirtCall(ILGenerator il, MethodInfo method)
4958+
private static bool EmitMethodCallOrVirtualCall(ILGenerator il, MethodInfo method)
49574959
{
49584960
#if SUPPORTS_EMITCALL
49594961
il.EmitCall(method.IsVirtual ? OpCodes.Callvirt : OpCodes.Call, method, null);
@@ -5166,7 +5168,7 @@ internal static MethodInfo FindMethod(this Type type, string methodName)
51665168
}
51675169

51685170
internal static MethodInfo DelegateTargetGetterMethod =
5169-
typeof(Delegate).FindPropertyGetMethod("Target");
5171+
typeof(Delegate).GetProperty(nameof(Delegate.Target)).GetMethod;
51705172

51715173
internal static MethodInfo FindDelegateInvokeMethod(this Type type) => type.GetMethod("Invoke");
51725174

@@ -5183,63 +5185,17 @@ internal static MethodInfo FindNullableGetValueOrDefaultMethod(this Type type)
51835185
return null;
51845186
}
51855187

5186-
internal static MethodInfo FindValueGetterMethod(this Type type) =>
5187-
type.FindPropertyGetMethod("Value");
5188-
5189-
internal static MethodInfo FindNullableHasValueGetterMethod(this Type type) =>
5190-
type.FindPropertyGetMethod("HasValue");
5191-
5192-
internal static MethodInfo FindPropertyGetMethod(this Type propHolderType, string propName)
5193-
{
5194-
var methods = propHolderType.GetMethods();
5195-
for (var i = 0; i < methods.Length; i++)
5196-
{
5197-
var method = methods[i];
5198-
if (method.IsSpecialName)
5199-
{
5200-
var methodName = method.Name;
5201-
if (methodName.Length == propName.Length + 4 && methodName[0] == 'g' && methodName[3] == '_')
5202-
{
5203-
var j = propName.Length - 1;
5204-
while (j != -1 && propName[j] == methodName[j + 4]) --j;
5205-
if (j == -1)
5206-
return method;
5207-
}
5208-
}
5209-
}
5210-
5211-
return propHolderType.BaseType?.FindPropertyGetMethod(propName);
5212-
}
5213-
5214-
internal static MethodInfo FindPropertySetMethod(this Type propHolderType, string propName)
5215-
{
5216-
var methods = propHolderType.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
5217-
for (var i = 0; i < methods.Length; i++)
5218-
{
5219-
var method = methods[i];
5220-
if (method.IsSpecialName)
5221-
{
5222-
var methodName = method.Name;
5223-
if (methodName.Length == propName.Length + 4 && methodName[0] == 's' && methodName[3] == '_')
5224-
{
5225-
var j = propName.Length - 1;
5226-
while (j != -1 && propName[j] == methodName[j + 4]) --j;
5227-
if (j == -1)
5228-
return method;
5229-
}
5230-
}
5231-
}
5188+
internal static MethodInfo FindValueGetterMethod(this Type type) => type.GetProperty("Value").GetMethod;
52325189

5233-
return propHolderType.BaseType?.FindPropertySetMethod(propName);
5234-
}
5190+
internal static MethodInfo FindNullableHasValueGetterMethod(this Type type) => type.GetProperty("HasValue").GetMethod;
52355191

52365192
internal static MethodInfo FindConvertOperator(this Type type, Type sourceType, Type targetType)
52375193
{
5238-
var methods = type.GetMethods();
5194+
var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
52395195
for (var i = 0; i < methods.Length; i++)
52405196
{
52415197
var m = methods[i];
5242-
if (m.IsStatic && m.IsSpecialName && m.ReturnType == targetType)
5198+
if (m.IsSpecialName && m.ReturnType == targetType)
52435199
{
52445200
var n = m.Name;
52455201
// n == "op_Implicit" || n == "op_Explicit"
@@ -5255,7 +5211,7 @@ internal static MethodInfo FindConvertOperator(this Type type, Type sourceType,
52555211

52565212
internal static ConstructorInfo FindSingleParamConstructor(this Type type, Type paramType)
52575213
{
5258-
var ctors = type.GetConstructors();
5214+
var ctors = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
52595215
for (var i = 0; i < ctors.Length; i++)
52605216
{
52615217
var ctor = ctors[i];

0 commit comments

Comments
 (0)