diff options
author | Jon Hanna <jon@hackcraft.net> | 2018-01-05 02:03:19 +0300 |
---|---|---|
committer | Omar Tawfik <OmarTawfik@users.noreply.github.com> | 2018-01-05 02:03:19 +0300 |
commit | e2303e9920e2060326e7c788a47f6b6e98fdd491 (patch) | |
tree | 7e998c86fce612b959e4207f4b39963d688c5aa4 /src/System.Linq.Expressions | |
parent | 53cb950f125a2c031f63dd181351164190250cda (diff) |
Update byref of custom S.L.Expressions convert method in interpreter (#25836)
Fixes #18445
Diffstat (limited to 'src/System.Linq.Expressions')
-rw-r--r-- | src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LightCompiler.cs | 43 | ||||
-rw-r--r-- | src/System.Linq.Expressions/tests/Convert/ConvertTests.cs | 17 |
2 files changed, 38 insertions, 22 deletions
diff --git a/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LightCompiler.cs b/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LightCompiler.cs index fb97dc39af..2c3d70ff94 100644 --- a/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LightCompiler.cs +++ b/src/System.Linq.Expressions/src/System/Linq/Expressions/Interpreter/LightCompiler.cs @@ -1038,13 +1038,35 @@ namespace System.Linq.Expressions.Interpreter { BranchLabel end = _instructions.MakeLabel(); BranchLabel loadDefault = _instructions.MakeLabel(); + MethodInfo method = node.Method; + ParameterInfo[] parameters = method.GetParametersCached(); + Debug.Assert(parameters.Length == 1); + ParameterInfo parameter = parameters[0]; + Expression operand = node.Operand; + Type operandType = operand.Type; + LocalDefinition opTemp = _locals.DefineLocal(Expression.Parameter(operandType), _instructions.Count); + ByRefUpdater updater = null; + Type parameterType = parameter.ParameterType; + if (parameterType.IsByRef) + { + if (node.IsLifted) + { + Compile(node.Operand); + } + else + { + updater = CompileAddress(node.Operand, 0); + parameterType = parameterType.GetElementType(); + } + } + else + { + Compile(node.Operand); + } - LocalDefinition opTemp = _locals.DefineLocal(Expression.Parameter(node.Operand.Type), _instructions.Count); - Compile(node.Operand); _instructions.EmitStoreLocal(opTemp.Index); - if (!node.Operand.Type.IsValueType || - (node.Operand.Type.IsNullableType() && node.IsLiftedToNull)) + if (!operandType.IsValueType || operandType.IsNullableType() && node.IsLiftedToNull) { _instructions.EmitLoadLocal(opTemp.Index); _instructions.EmitLoad(null, typeof(object)); @@ -1053,13 +1075,20 @@ namespace System.Linq.Expressions.Interpreter } _instructions.EmitLoadLocal(opTemp.Index); - if (node.Operand.Type.IsNullableType() && - node.Method.GetParametersCached()[0].ParameterType.Equals(node.Operand.Type.GetNonNullableType())) + if (operandType.IsNullableType() && parameterType.Equals(operandType.GetNonNullableType())) { _instructions.Emit(NullableMethodCallInstruction.CreateGetValue()); } - _instructions.EmitCall(node.Method); + if (updater == null) + { + _instructions.EmitCall(method); + } + else + { + _instructions.EmitByRefCall(method, parameters, new[] {updater}); + updater.UndefineTemps(_instructions, _locals); + } _instructions.EmitBranch(end, hasResult: false, hasValue: true); diff --git a/src/System.Linq.Expressions/tests/Convert/ConvertTests.cs b/src/System.Linq.Expressions/tests/Convert/ConvertTests.cs index b8d2b8032b..f02fbba0bd 100644 --- a/src/System.Linq.Expressions/tests/Convert/ConvertTests.cs +++ b/src/System.Linq.Expressions/tests/Convert/ConvertTests.cs @@ -16808,7 +16808,8 @@ namespace System.Linq.Expressions.Tests Assert.Equal(5, x); // Refness is lost on lifting. } - private static void CustomConversionNotStandardNameFromByRef(bool useInterpreter) + [Theory, ClassData(typeof(CompilationTypes))] + public static void CustomConversionNotStandardNameFromByRef(bool useInterpreter) { var param = Expression.Parameter(typeof(int).MakeByRefType()); MethodInfo method = typeof(CustomConversions).GetMethod(nameof(CustomConversions.ConvertFromRefInt)); @@ -16820,20 +16821,6 @@ namespace System.Linq.Expressions.Tests Assert.Equal(6, x); } - [Fact, ActiveIssue(18445)] - public static void CustomConversionNotStandardNameFromByRefInterpreter() - { - CustomConversionNotStandardNameFromByRef(useInterpreter: true); - } - -#if FEATURE_COMPILE - [Fact] - public static void CustomConversionNotStandardNameFromByRefCompiler() - { - CustomConversionNotStandardNameFromByRef(useInterpreter: false); - } -#endif - [Fact] public static void CustomConversionNotStandardNameToWrongType() { |