private void ProcessCallSiteCaching(IfStatement theIf, FieldDefinition callSiteField) { MethodInvocationExpression binderMethodInvocation = GetBinderMethodInvocation(theIf.Then.Statements.Last() as ExpressionStatement, callSiteField); CallSiteInfo callSiteInfo = new CallSiteInfo(callSiteField, binderMethodInvocation.MethodExpression.Method.Name); int index = 0; if (callSiteInfo.BinderType == CallSiteBinderType.GetMember || callSiteInfo.BinderType == CallSiteBinderType.InvokeMember || callSiteInfo.BinderType == CallSiteBinderType.SetMember || callSiteInfo.BinderType == CallSiteBinderType.IsEvent) { GetMemberNameArgument(binderMethodInvocation, callSiteInfo); } if (callSiteInfo.BinderType == CallSiteBinderType.BinaryOperation || callSiteInfo.BinderType == CallSiteBinderType.UnaryOperation) { GetOperatorArgument(binderMethodInvocation, callSiteInfo); } if (callSiteInfo.BinderType == CallSiteBinderType.Convert) { GetConvertTypeArgument(binderMethodInvocation, callSiteInfo); } if (callSiteInfo.BinderType == CallSiteBinderType.InvokeMember) { VariableReference typeArrayVariable = GetTypeArrayVariable(binderMethodInvocation); if (typeArrayVariable != null) { callSiteInfo.GenericTypeArguments = new List <TypeReference>(); ProcessArgumentArray(theIf.Then.Statements, ref index, typeArrayVariable, callSiteInfo, GetGenericTypeArgument); } } if (callSiteInfo.BinderType != CallSiteBinderType.Convert && callSiteInfo.BinderType != CallSiteBinderType.IsEvent) { ProcessArgumentArray(theIf.Then.Statements, ref index, GetArgumentArrayVariable(binderMethodInvocation), callSiteInfo, GetDynamicArgument); } else { callSiteInfo.DynamicArgumentIndices.Add(0); } fieldToCallSiteInfoMap.Add(callSiteField, callSiteInfo); }
private void ProcessCallSiteCaching(IfStatement theIf, FieldDefinition callSiteField) { V_0 = this.GetBinderMethodInvocation(theIf.get_Then().get_Statements().Last <Statement>() as ExpressionStatement, callSiteField); V_1 = new CallSiteInfo(callSiteField, V_0.get_MethodExpression().get_Method().get_Name()); V_2 = 0; if (V_1.get_BinderType() == 3 || V_1.get_BinderType() == 6 || V_1.get_BinderType() == 9 || V_1.get_BinderType() == 7) { this.GetMemberNameArgument(V_0, V_1); } if (V_1.get_BinderType() == CallSiteBinderType.BinaryOperation || V_1.get_BinderType() == 10) { this.GetOperatorArgument(V_0, V_1); } if (V_1.get_BinderType() == 1) { this.GetConvertTypeArgument(V_0, V_1); } if (V_1.get_BinderType() == 6) { V_3 = this.GetTypeArrayVariable(V_0); if (V_3 != null) { V_1.set_GenericTypeArguments(new List <TypeReference>()); this.ProcessArgumentArray(theIf.get_Then().get_Statements(), ref V_2, V_3, V_1, new Action <MethodInvocationExpression, int, CallSiteInfo>(this.GetGenericTypeArgument)); } } if (V_1.get_BinderType() == 1 || V_1.get_BinderType() == 7) { V_1.get_DynamicArgumentIndices().Add(0); } else { this.ProcessArgumentArray(theIf.get_Then().get_Statements(), ref V_2, this.GetArgumentArrayVariable(V_0), V_1, new Action <MethodInvocationExpression, int, CallSiteInfo>(this.GetDynamicArgument)); } this.fieldToCallSiteInfoMap.Add(callSiteField, V_1); return; }
private void GetDynamicArgument(MethodInvocationExpression expression, int index, CallSiteInfo callSiteInfo) { if (expression.MethodExpression.Method.Name != "Create" || expression.MethodExpression.Target != null || expression.MethodExpression.Method.DeclaringType.GetFriendlyFullName(null) != "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo" || expression.Arguments.Count != 2 || expression.Arguments[0].CodeNodeType != CodeNodeType.LiteralExpression) { throw new Exception(InvalidStatementExceptionString); } int argumentInfoFlag = Convert.ToInt32((expression.Arguments[0] as LiteralExpression).Value); if ((argumentInfoFlag & UseCompileTimeType) == 0) { callSiteInfo.DynamicArgumentIndices.Add(index); } }
private void GetGenericTypeArgument(MethodInvocationExpression expression, int index, CallSiteInfo callSiteInfo) { TypeReference typeRef; if (!expression.IsTypeOfExpression(out typeRef)) { throw new Exception(InvalidStatementExceptionString); } callSiteInfo.GenericTypeArguments.Add(typeRef); }
private void ProcessArgumentArray(StatementCollection statements, ref int index, VariableReference typesArray, CallSiteInfo callSiteInfo, Action <MethodInvocationExpression, int, CallSiteInfo> action) { if ((statements[index] is ExpressionStatement) && ((statements[index] as ExpressionStatement).Expression is BinaryExpression)) { BinaryExpression binaryExpression = (statements[index] as ExpressionStatement).Expression as BinaryExpression; if (binaryExpression.IsAssignmentExpression && (binaryExpression.Left is VariableReferenceExpression) && (binaryExpression.Right is MethodInvocationExpression)) { index++; } } int arraySize = CheckNewArrayInitializationAndSize(statements[index++], typesArray); for (int i = 0; i < arraySize; i++) { if (!statements[index].IsAssignmentStatement()) { throw new Exception(InvalidStatementExceptionString); } BinaryExpression elementAssignment = (statements[index++] as ExpressionStatement).Expression as BinaryExpression; if (elementAssignment.Left.CodeNodeType != CodeNodeType.ArrayIndexerExpression || !CheckArrayIndexerExpression(elementAssignment.Left as ArrayIndexerExpression, typesArray, i) || elementAssignment.Right.CodeNodeType != CodeNodeType.MethodInvocationExpression) { throw new Exception(InvalidStatementExceptionString); } action(elementAssignment.Right as MethodInvocationExpression, i, callSiteInfo); } }
private void GetConvertTypeArgument(MethodInvocationExpression binderInvocation, CallSiteInfo callSiteInfo) { int typeArgumentIndex = 1; TypeReference typeRef; if (binderInvocation.Arguments[typeArgumentIndex].CodeNodeType != CodeNodeType.MethodInvocationExpression || !(binderInvocation.Arguments[typeArgumentIndex] as MethodInvocationExpression).IsTypeOfExpression(out typeRef)) { throw new Exception("Invalid argument: convert type."); } callSiteInfo.ConvertType = typeRef; }
private void GetOperatorArgument(MethodInvocationExpression binderInvocation, CallSiteInfo callSiteInfo) { int operatorIndex = 1; if (binderInvocation.Arguments[operatorIndex].CodeNodeType != CodeNodeType.LiteralExpression) { throw new Exception("Invalid argument: operator."); } callSiteInfo.Operator = (ExpressionType)Convert.ToInt32((binderInvocation.Arguments[operatorIndex] as LiteralExpression).Value); }
private void GetMemberNameArgument(MethodInvocationExpression binderInvocation, CallSiteInfo callSiteInfo) { int memberNameIndex = 1; if (binderInvocation.Arguments[memberNameIndex].CodeNodeType == CodeNodeType.LiteralExpression) { callSiteInfo.MemberName = (binderInvocation.Arguments[memberNameIndex] as LiteralExpression).Value as string; if (callSiteInfo.MemberName != null) { return; } } throw new Exception("Invalid argument: member name."); }
private void GetDynamicArgument(MethodInvocationExpression expression, int index, CallSiteInfo callSiteInfo) { if (String.op_Inequality(expression.get_MethodExpression().get_Method().get_Name(), "Create") || expression.get_MethodExpression().get_Target() != null || String.op_Inequality(expression.get_MethodExpression().get_Method().get_DeclaringType().GetFriendlyFullName(null), "Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo") || expression.get_Arguments().get_Count() != 2 || expression.get_Arguments().get_Item(0).get_CodeNodeType() != 22) { throw new Exception("Invalid statement."); } if (Convert.ToInt32((expression.get_Arguments().get_Item(0) as LiteralExpression).get_Value()) & 1 == 0) { callSiteInfo.get_DynamicArgumentIndices().Add(index); } return; }
ILInstruction MakeDynamicInstruction(CallSiteInfo callsite, CallVirt targetInvokeCall, List <ILInstruction> deadArguments) { switch (callsite.Kind) { case BinderMethodKind.BinaryOperation: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicBinaryOperatorInstruction( binderFlags: callsite.Flags, operation: callsite.Operation, context: callsite.Context, leftArgumentInfo: callsite.ArgumentInfos[0], left: targetInvokeCall.Arguments[2], rightArgumentInfo: callsite.ArgumentInfos[1], right: targetInvokeCall.Arguments[3] )); case BinderMethodKind.Convert: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); ILInstruction result = new DynamicConvertInstruction( binderFlags: callsite.Flags, context: callsite.Context, type: callsite.ConvertTargetType, argument: targetInvokeCall.Arguments[2] ); if (result.ResultType == StackType.Unknown) { // if references are missing, we need to coerce the primitive type to None. // Otherwise we will get loads of assertions. result = new Conv(result, PrimitiveType.None, ((DynamicConvertInstruction)result).IsChecked, Sign.None); } return(result); case BinderMethodKind.GetIndex: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicGetIndexInstruction( binderFlags: callsite.Flags, context: callsite.Context, argumentInfo: callsite.ArgumentInfos, arguments: targetInvokeCall.Arguments.Skip(2).ToArray() )); case BinderMethodKind.GetMember: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicGetMemberInstruction( binderFlags: callsite.Flags, name: callsite.MemberName, context: callsite.Context, targetArgumentInfo: callsite.ArgumentInfos[0], target: targetInvokeCall.Arguments[2] )); case BinderMethodKind.Invoke: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicInvokeInstruction( binderFlags: callsite.Flags, context: callsite.Context, argumentInfo: callsite.ArgumentInfos, arguments: targetInvokeCall.Arguments.Skip(2).ToArray() )); case BinderMethodKind.InvokeConstructor: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicInvokeConstructorInstruction( binderFlags: callsite.Flags, context: callsite.Context, argumentInfo: callsite.ArgumentInfos, arguments: targetInvokeCall.Arguments.Skip(2).ToArray() )); case BinderMethodKind.InvokeMember: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicInvokeMemberInstruction( binderFlags: callsite.Flags, name: callsite.MemberName, typeArguments: callsite.TypeArguments, context: callsite.Context, argumentInfo: callsite.ArgumentInfos, arguments: targetInvokeCall.Arguments.Skip(2).ToArray() )); case BinderMethodKind.IsEvent: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicIsEventInstruction( binderFlags: callsite.Flags, name: callsite.MemberName, context: callsite.Context, argument: targetInvokeCall.Arguments[2] )); case BinderMethodKind.SetIndex: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicSetIndexInstruction( binderFlags: callsite.Flags, context: callsite.Context, argumentInfo: callsite.ArgumentInfos, arguments: targetInvokeCall.Arguments.Skip(2).ToArray() )); case BinderMethodKind.SetMember: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicSetMemberInstruction( binderFlags: callsite.Flags, name: callsite.MemberName, context: callsite.Context, targetArgumentInfo: callsite.ArgumentInfos[0], target: targetInvokeCall.Arguments[2], valueArgumentInfo: callsite.ArgumentInfos[1], value: targetInvokeCall.Arguments[3] )); case BinderMethodKind.UnaryOperation: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicUnaryOperatorInstruction( binderFlags: callsite.Flags, operation: callsite.Operation, context: callsite.Context, operandArgumentInfo: callsite.ArgumentInfos[0], operand: targetInvokeCall.Arguments[2] )); default: throw new ArgumentOutOfRangeException($"Value {callsite.Kind} is not supported!"); } }
private void ProcessArgumentArray(StatementCollection statements, ref int index, VariableReference typesArray, CallSiteInfo callSiteInfo, Action <MethodInvocationExpression, int, CallSiteInfo> action) { if (statements.get_Item(index) as ExpressionStatement != null && (statements.get_Item(index) as ExpressionStatement).get_Expression() as BinaryExpression != null) { V_1 = (statements.get_Item(index) as ExpressionStatement).get_Expression() as BinaryExpression; if (V_1.get_IsAssignmentExpression() && V_1.get_Left() as VariableReferenceExpression != null && V_1.get_Right() as MethodInvocationExpression != null) { index = index + 1; } } V_2 = index; index = V_2 + 1; V_0 = this.CheckNewArrayInitializationAndSize(statements.get_Item(V_2), typesArray); V_3 = 0; while (V_3 < V_0) { if (!statements.get_Item(index).IsAssignmentStatement()) { throw new Exception("Invalid statement."); } V_2 = index; index = V_2 + 1; V_4 = (statements.get_Item(V_2) as ExpressionStatement).get_Expression() as BinaryExpression; if (V_4.get_Left().get_CodeNodeType() != 39 || !this.CheckArrayIndexerExpression(V_4.get_Left() as ArrayIndexerExpression, typesArray, V_3) || V_4.get_Right().get_CodeNodeType() != 19) { throw new Exception("Invalid statement."); } action.Invoke(V_4.get_Right() as MethodInvocationExpression, V_3, callSiteInfo); V_3 = V_3 + 1; } return; }
private void GetOperatorArgument(MethodInvocationExpression binderInvocation, CallSiteInfo callSiteInfo) { V_0 = 1; if (binderInvocation.get_Arguments().get_Item(V_0).get_CodeNodeType() != 22) { throw new Exception("Invalid argument: operator."); } callSiteInfo.set_Operator(Convert.ToInt32((binderInvocation.get_Arguments().get_Item(V_0) as LiteralExpression).get_Value())); return; }
private void GetMemberNameArgument(MethodInvocationExpression binderInvocation, CallSiteInfo callSiteInfo) { V_0 = 1; if (binderInvocation.get_Arguments().get_Item(V_0).get_CodeNodeType() == 22) { callSiteInfo.set_MemberName((binderInvocation.get_Arguments().get_Item(V_0) as LiteralExpression).get_Value() as String); if (callSiteInfo.get_MemberName() != null) { return; } } throw new Exception("Invalid argument: member name."); }
private void GetGenericTypeArgument(MethodInvocationExpression expression, int index, CallSiteInfo callSiteInfo) { if (!expression.IsTypeOfExpression(out V_0)) { throw new Exception("Invalid statement."); } callSiteInfo.get_GenericTypeArguments().Add(V_0); return; }
ILInstruction MakeDynamicInstruction(CallSiteInfo callsite, CallVirt targetInvokeCall, List <ILInstruction> deadArguments) { switch (callsite.Kind) { case BinderMethodKind.BinaryOperation: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicBinaryOperatorInstruction( binderFlags: callsite.Flags, operation: callsite.Operation, context: callsite.Context, leftArgumentInfo: callsite.ArgumentInfos[0], left: targetInvokeCall.Arguments[2], rightArgumentInfo: callsite.ArgumentInfos[1], right: targetInvokeCall.Arguments[3] )); case BinderMethodKind.Convert: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); ILInstruction result = new DynamicConvertInstruction( binderFlags: callsite.Flags, context: callsite.Context, type: callsite.ConvertTargetType, argument: targetInvokeCall.Arguments[2] ); if (result.ResultType == StackType.Unknown) { // if references are missing, we need to coerce the primitive type to None. // Otherwise we will get loads of assertions. result = new Conv(result, PrimitiveType.None, ((DynamicConvertInstruction)result).IsChecked, Sign.None); } return(result); case BinderMethodKind.GetIndex: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicGetIndexInstruction( binderFlags: callsite.Flags, context: callsite.Context, argumentInfo: callsite.ArgumentInfos, arguments: targetInvokeCall.Arguments.Skip(2).ToArray() )); case BinderMethodKind.GetMember: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicGetMemberInstruction( binderFlags: callsite.Flags, name: callsite.MemberName, context: callsite.Context, targetArgumentInfo: callsite.ArgumentInfos[0], target: targetInvokeCall.Arguments[2] )); case BinderMethodKind.Invoke: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicInvokeInstruction( binderFlags: callsite.Flags, context: callsite.Context, argumentInfo: callsite.ArgumentInfos, arguments: targetInvokeCall.Arguments.Skip(2).ToArray() )); case BinderMethodKind.InvokeConstructor: var arguments = targetInvokeCall.Arguments.Skip(2).ToArray(); // Extract type information from targetInvokeCall: // Must either be an inlined type or // a reference to a variable that is initialized with a type. if (!TransformExpressionTrees.MatchGetTypeFromHandle(arguments[0], out var type)) { if (!(arguments[0].MatchLdLoc(out var temp) && temp.IsSingleDefinition && temp.StoreInstructions.FirstOrDefault() is StLoc initStore)) { return(null); } if (!TransformExpressionTrees.MatchGetTypeFromHandle(initStore.Value, out type)) { return(null); } } deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicInvokeConstructorInstruction( binderFlags: callsite.Flags, type: type ?? SpecialType.UnknownType, context: callsite.Context, argumentInfo: callsite.ArgumentInfos, arguments: arguments )); case BinderMethodKind.InvokeMember: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicInvokeMemberInstruction( binderFlags: callsite.Flags, name: callsite.MemberName, typeArguments: callsite.TypeArguments, context: callsite.Context, argumentInfo: callsite.ArgumentInfos, arguments: targetInvokeCall.Arguments.Skip(2).ToArray() )); case BinderMethodKind.IsEvent: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicIsEventInstruction( binderFlags: callsite.Flags, name: callsite.MemberName, context: callsite.Context, argument: targetInvokeCall.Arguments[2] )); case BinderMethodKind.SetIndex: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicSetIndexInstruction( binderFlags: callsite.Flags, context: callsite.Context, argumentInfo: callsite.ArgumentInfos, arguments: targetInvokeCall.Arguments.Skip(2).ToArray() )); case BinderMethodKind.SetMember: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicSetMemberInstruction( binderFlags: callsite.Flags, name: callsite.MemberName, context: callsite.Context, targetArgumentInfo: callsite.ArgumentInfos[0], target: targetInvokeCall.Arguments[2], valueArgumentInfo: callsite.ArgumentInfos[1], value: targetInvokeCall.Arguments[3] )); case BinderMethodKind.UnaryOperation: deadArguments.AddRange(targetInvokeCall.Arguments.Take(2)); return(new DynamicUnaryOperatorInstruction( binderFlags: callsite.Flags, operation: callsite.Operation, context: callsite.Context, operandArgumentInfo: callsite.ArgumentInfos[0], operand: targetInvokeCall.Arguments[2] )); default: throw new ArgumentOutOfRangeException($"Value {callsite.Kind} is not supported!"); } }
bool ScanCallSiteInitBlock(Block callSiteInitBlock, IField callSiteCacheField, IType callSiteDelegateType, out CallSiteInfo callSiteInfo, out Block blockAfterInit) { callSiteInfo = default(CallSiteInfo); blockAfterInit = null; int instCount = callSiteInitBlock.Instructions.Count; if (callSiteInitBlock.IncomingEdgeCount != 1 || instCount < 2) { return(false); } if (!callSiteInitBlock.Instructions[instCount - 1].MatchBranch(out blockAfterInit)) { return(false); } if (!callSiteInitBlock.Instructions[instCount - 2].MatchStsFld(out var field, out var value) || !field.Equals(callSiteCacheField)) { return(false); } if (!(value is Call createBinderCall) || createBinderCall.Method.TypeArguments.Count != 0 || createBinderCall.Arguments.Count != 1 || createBinderCall.Method.Name != "Create" || createBinderCall.Method.DeclaringType.FullName != CallSiteTypeName || createBinderCall.Method.DeclaringType.TypeArguments.Count != 1) { return(false); } if (!(createBinderCall.Arguments[0] is Call binderCall) || binderCall.Method.DeclaringType.FullName != CSharpBinderTypeName || binderCall.Method.DeclaringType.TypeParameterCount != 0) { return(false); } callSiteInfo.DelegateType = callSiteDelegateType; callSiteInfo.InitBlock = callSiteInitBlock; switch (binderCall.Method.Name) { case "IsEvent": callSiteInfo.Kind = BinderMethodKind.IsEvent; // In the case of Binder.IsEvent all arguments should already be properly inlined, as there is no array initializer: // Scan arguments: binder flags, member name, context type if (binderCall.Arguments.Count != 3) { return(false); } if (!binderCall.Arguments[0].MatchLdcI4(out int binderFlagsInteger)) { return(false); } callSiteInfo.Flags = (CSharpBinderFlags)binderFlagsInteger; if (!binderCall.Arguments[1].MatchLdStr(out string name)) { return(false); } callSiteInfo.MemberName = name; if (!TransformExpressionTrees.MatchGetTypeFromHandle(binderCall.Arguments[2], out var contextType)) { return(false); } callSiteInfo.Context = contextType; return(true); case "Convert": callSiteInfo.Kind = BinderMethodKind.Convert; // In the case of Binder.Convert all arguments should already be properly inlined, as there is no array initializer: // Scan arguments: binder flags, target type, context type if (binderCall.Arguments.Count != 3) { return(false); } if (!binderCall.Arguments[0].MatchLdcI4(out binderFlagsInteger)) { return(false); } callSiteInfo.Flags = (CSharpBinderFlags)binderFlagsInteger; if (!TransformExpressionTrees.MatchGetTypeFromHandle(binderCall.Arguments[1], out var targetType)) { return(false); } callSiteInfo.ConvertTargetType = targetType; if (!TransformExpressionTrees.MatchGetTypeFromHandle(binderCall.Arguments[2], out contextType)) { return(false); } callSiteInfo.Context = contextType; return(true); case "InvokeMember": callSiteInfo.Kind = BinderMethodKind.InvokeMember; if (binderCall.Arguments.Count != 5) { return(false); } // First argument: binder flags // The value must be a single ldc.i4 instruction. if (!binderCall.Arguments[0].MatchLdLoc(out var variable)) { return(false); } if (!callSiteInitBlock.Instructions[0].MatchStLoc(variable, out value)) { return(false); } if (!value.MatchLdcI4(out binderFlagsInteger)) { return(false); } callSiteInfo.Flags = (CSharpBinderFlags)binderFlagsInteger; // Second argument: method name // The value must be a single ldstr instruction. if (!binderCall.Arguments[1].MatchLdLoc(out variable)) { return(false); } if (!callSiteInitBlock.Instructions[1].MatchStLoc(variable, out value)) { return(false); } if (!value.MatchLdStr(out name)) { return(false); } callSiteInfo.MemberName = name; // Third argument: type arguments // The value must be either ldnull (no type arguments) or an array initializer pattern. if (!binderCall.Arguments[2].MatchLdLoc(out variable)) { return(false); } if (!callSiteInitBlock.Instructions[2].MatchStLoc(out var variableOrTemporary, out value)) { return(false); } int numberOfTypeArguments = 0; if (!value.MatchLdNull()) { if (value is NewArr typeArgsNewArr && typeArgsNewArr.Type.IsKnownType(KnownTypeCode.Type) && typeArgsNewArr.Indices.Count == 1 && typeArgsNewArr.Indices[0].MatchLdcI4(out numberOfTypeArguments)) { if (!TransformArrayInitializers.HandleSimpleArrayInitializer(context.Function, callSiteInitBlock, 3, variableOrTemporary, typeArgsNewArr.Type, new[] { numberOfTypeArguments }, out var typeArguments, out _)) { return(false); } int i = 0; callSiteInfo.TypeArguments = new IType[numberOfTypeArguments]; foreach (var(_, typeArg) in typeArguments) { if (!TransformExpressionTrees.MatchGetTypeFromHandle(typeArg, out var type)) { return(false); } callSiteInfo.TypeArguments[i] = type; i++; } } else { return(false); } } int typeArgumentsOffset = numberOfTypeArguments; // Special case for csc array initializers: if (variableOrTemporary != variable) { // store temporary from array initializer in variable if (!callSiteInitBlock.Instructions[3 + typeArgumentsOffset].MatchStLoc(variable, out value)) { return(false); } if (!value.MatchLdLoc(variableOrTemporary)) { return(false); } typeArgumentsOffset++; } // Fourth argument: context type if (!binderCall.Arguments[3].MatchLdLoc(out variable)) { return(false); } if (!callSiteInitBlock.Instructions[3 + typeArgumentsOffset].MatchStLoc(variable, out value)) { return(false); } if (!TransformExpressionTrees.MatchGetTypeFromHandle(value, out contextType)) { return(false); } callSiteInfo.Context = contextType; // Fifth argument: call parameter info if (!binderCall.Arguments[4].MatchLdLoc(out variable)) { return(false); } if (!callSiteInitBlock.Instructions[4 + typeArgumentsOffset].MatchStLoc(variable, out value)) { return(false); } if (!ExtractArgumentInfo(value, ref callSiteInfo, 5 + typeArgumentsOffset, variable)) { return(false); } return(true);
private void GetConvertTypeArgument(MethodInvocationExpression binderInvocation, CallSiteInfo callSiteInfo) { V_0 = 1; if (binderInvocation.get_Arguments().get_Item(V_0).get_CodeNodeType() != 19 || !(binderInvocation.get_Arguments().get_Item(V_0) as MethodInvocationExpression).IsTypeOfExpression(out V_1)) { throw new Exception("Invalid argument: convert type."); } callSiteInfo.set_ConvertType(V_1); return; }