private Expression GenerateInvokeMemeberExpression(CallSiteInfo callSiteInfo, IList <Expression> arguments, IEnumerable <Instruction> instructions) { if (arguments.Count < 1) { throw new Exception("Invalid number of arguments for invoke expression."); } Expression target; TypeReference typeRef; if (arguments[0].CodeNodeType == CodeNodeType.MethodInvocationExpression && (arguments[0] as MethodInvocationExpression).IsTypeOfExpression(out typeRef)) { target = new TypeReferenceExpression(typeRef, arguments[0].UnderlyingSameMethodInstructions); } else { target = arguments[0]; } DynamicMemberReferenceExpression dynamicMemberReferenceExpression = new DynamicMemberReferenceExpression(target, callSiteInfo.MemberName, objectTypeRef, instructions, GetAllButFirst(arguments), callSiteInfo.GenericTypeArguments); return(dynamicMemberReferenceExpression); }
private void MarkDynamicArguments(CallSiteInfo callSiteInfo, IList <Expression> arguments) { V_0 = callSiteInfo.get_DynamicArgumentIndices().GetEnumerator(); try { while (V_0.MoveNext()) { V_1 = V_0.get_Current(); if (arguments.get_Item(V_1).get_CodeNodeType() == 24 || arguments.get_Item(V_1).get_CodeNodeType() == 23 && (arguments.get_Item(V_1) as UnaryExpression).get_Operator() == 11 || arguments.get_Item(V_1).get_CodeNodeType() == 61 || arguments.get_Item(V_1).get_CodeNodeType() == 59 || DynamicElementAnalyzer.Analyze(arguments.get_Item(V_1))) { continue; } V_2 = new ExplicitCastExpression(arguments.get_Item(V_1), this.objectTypeRef, null); stackVariable40 = new Boolean[1]; stackVariable40[0] = true; V_2.set_DynamicPositioningFlags(stackVariable40); arguments.set_Item(V_1, V_2); } } finally { ((IDisposable)V_0).Dispose(); } return; }
private Expression GenerateGetMemberExpression(CallSiteInfo callSiteInfo, IList <Expression> arguments, IEnumerable <Instruction> instructions) { if (arguments.get_Count() != 1) { throw new Exception("Invalid number of arguments for get member expression."); } return(new DynamicMemberReferenceExpression(arguments.get_Item(0), callSiteInfo.get_MemberName(), this.objectTypeRef, instructions)); }
private Expression GenerateSetMemberExpression(CallSiteInfo callSiteInfo, IList <Expression> arguments, IEnumerable <Instruction> instructions) { if (arguments.get_Count() != 2) { throw new Exception("Invalid number of arguments for set index expression."); } return(new BinaryExpression(26, new DynamicMemberReferenceExpression(arguments.get_Item(0), callSiteInfo.get_MemberName(), this.objectTypeRef, instructions), arguments.get_Item(1), this.typeSystem, null, false)); }
private Expression GenerateConvertExpression(CallSiteInfo callSiteInfo, IList <Expression> arguments, IEnumerable <Instruction> instructions) { if (arguments.get_Count() != 1) { throw new Exception("Invalid number of arguments for convert expression."); } return(new ExplicitCastExpression(arguments.get_Item(0), callSiteInfo.get_ConvertType(), instructions)); }
private Expression GenerateBinaryExpression(CallSiteInfo callSiteInfo, IList <Expression> arguments, IEnumerable <Instruction> instructions) { if (arguments.get_Count() != 2) { throw new Exception("Invalid number of arguments for binary expression."); } return(new BinaryExpression(DynamicHelper.GetBinaryOperator(callSiteInfo.get_Operator()), arguments.get_Item(0), arguments.get_Item(1), this.objectTypeRef, this.typeSystem, instructions, false)); }
private Expression GenerateConvertExpression(CallSiteInfo callSiteInfo, IList <Expression> arguments, IEnumerable <Instruction> instructions) { if (arguments.Count != 1) { throw new Exception("Invalid number of arguments for convert expression."); } return(new CastExpression(arguments[0], callSiteInfo.ConvertType, instructions)); }
private Expression GenerateSetMemberExpression(CallSiteInfo callSiteInfo, IList <Expression> arguments, IEnumerable <Instruction> instructions) { if (arguments.Count != 2) { throw new Exception("Invalid number of arguments for set index expression."); } return(new BinaryExpression(BinaryOperator.Assign, new DynamicMemberReferenceExpression(arguments[0], callSiteInfo.MemberName, objectTypeRef, instructions), arguments[1], typeSystem, null)); }
private Expression GenerateUnaryExpression(CallSiteInfo callSiteInfo, IList <Expression> arguments, IEnumerable <Instruction> instructions) { if (arguments.get_Count() != 1) { throw new Exception("Invalid number of arguments for unary expression."); } if (callSiteInfo.get_Operator() == 83) { return(arguments.get_Item(0)); } return(new UnaryExpression(DynamicHelper.GetUnaryOperator(callSiteInfo.get_Operator()), arguments.get_Item(0), instructions)); }
private Expression GenerateBinaryExpression(CallSiteInfo callSiteInfo, IList <Expression> arguments, IEnumerable <Instruction> instructions) { if (arguments.Count != 2) { throw new Exception("Invalid number of arguments for binary expression."); } return(new BinaryExpression( DynamicHelper.GetBinaryOperator(callSiteInfo.Operator), arguments[0], arguments[1], objectTypeRef, typeSystem, instructions )); }
private Expression GenerateInvokeMemeberExpression(CallSiteInfo callSiteInfo, IList <Expression> arguments, IEnumerable <Instruction> instructions) { if (arguments.get_Count() < 1) { throw new Exception("Invalid number of arguments for invoke expression."); } if (arguments.get_Item(0).get_CodeNodeType() != 19 || !(arguments.get_Item(0) as MethodInvocationExpression).IsTypeOfExpression(out V_1)) { V_0 = arguments.get_Item(0); } else { V_0 = new TypeReferenceExpression(V_1, arguments.get_Item(0).get_UnderlyingSameMethodInstructions()); } return(new DynamicMemberReferenceExpression(V_0, callSiteInfo.get_MemberName(), this.objectTypeRef, instructions, this.GetAllButFirst(arguments), callSiteInfo.get_GenericTypeArguments())); }
private Expression GenerateUnaryExpression(CallSiteInfo callSiteInfo, IList <Expression> arguments, IEnumerable <Instruction> instructions) { if (arguments.Count != 1) { throw new Exception("Invalid number of arguments for unary expression."); } if (callSiteInfo.Operator != ExpressionType.IsTrue) { return(new UnaryExpression(DynamicHelper.GetUnaryOperator(callSiteInfo.Operator), arguments[0], instructions)); } else { return(arguments[0]); } }
private void MarkDynamicArguments(CallSiteInfo callSiteInfo, IList <Expression> arguments) { foreach (int index in callSiteInfo.DynamicArgumentIndices) { if (arguments[index].CodeNodeType != CodeNodeType.BinaryExpression && (arguments[index].CodeNodeType != CodeNodeType.UnaryExpression || (arguments[index] as UnaryExpression).Operator != UnaryOperator.None) && arguments[index].CodeNodeType != CodeNodeType.DynamicIndexerExpression && arguments[index].CodeNodeType != CodeNodeType.DynamicMemberReferenceExpression && !DynamicElementAnalyzer.Analyze(arguments[index])) { ExplicitCastExpression theCastExpression = new ExplicitCastExpression(arguments[index], objectTypeRef, null); theCastExpression.DynamicPositioningFlags = new bool[] { true }; arguments[index] = theCastExpression; } } }
private Expression GenerateExpression(CallSiteInfo callSiteInfo, IEnumerable <Expression> originalArguments, IEnumerable <Instruction> instructions) { IList <Expression> arguments = GetAllButFirst(originalArguments); MarkDynamicArguments(callSiteInfo, arguments); switch (callSiteInfo.BinderType) { case CallSiteBinderType.BinaryOperation: return(GenerateBinaryExpression(callSiteInfo, arguments, instructions)); case CallSiteBinderType.Convert: return(GenerateConvertExpression(callSiteInfo, arguments, instructions)); case CallSiteBinderType.GetIndex: return(GenerateGetIndexExpression(arguments, instructions)); case CallSiteBinderType.GetMember: return(GenerateGetMemberExpression(callSiteInfo, arguments, instructions)); case CallSiteBinderType.Invoke: return(GenerateInvokeExpression(callSiteInfo, arguments, instructions)); case CallSiteBinderType.InvokeConstructor: return(GenerateInvokeConstructorExpression(arguments, instructions)); case CallSiteBinderType.InvokeMember: return(GenerateInvokeMemeberExpression(callSiteInfo, arguments, instructions)); case CallSiteBinderType.SetIndex: return(GenerateSetIndexExpression(arguments, instructions)); case CallSiteBinderType.SetMember: return(GenerateSetMemberExpression(callSiteInfo, arguments, instructions)); case CallSiteBinderType.UnaryOperation: return(GenerateUnaryExpression(callSiteInfo, arguments, instructions)); } throw new Exception("Invalid binder type."); }
private Expression GenerateInvokeExpression(CallSiteInfo callSiteInfo, IList <Expression> arguments, IEnumerable <Instruction> instructions) { return(this.GenerateInvokeMemeberExpression(callSiteInfo, arguments, instructions)); }
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 Expression GenerateBinaryExpression(CallSiteInfo callSiteInfo, IList<Expression> arguments, IEnumerable<Instruction> instructions) { if (arguments.Count != 2) { throw new Exception("Invalid number of arguments for binary expression."); } return new BinaryExpression( DynamicHelper.GetBinaryOperator(callSiteInfo.Operator), arguments[0], arguments[1], objectTypeRef, typeSystem, instructions ); }
private Expression GenerateGetMemberExpression(CallSiteInfo callSiteInfo, IList<Expression> arguments, IEnumerable<Instruction> instructions) { if (arguments.Count != 1) { throw new Exception("Invalid number of arguments for get member expression."); } return new DynamicMemberReferenceExpression(arguments[0], callSiteInfo.MemberName, objectTypeRef, instructions); }
private void MarkDynamicArguments(CallSiteInfo callSiteInfo, IList<Expression> arguments) { foreach (int index in callSiteInfo.DynamicArgumentIndices) { if (arguments[index].CodeNodeType != CodeNodeType.BinaryExpression && (arguments[index].CodeNodeType != CodeNodeType.UnaryExpression || (arguments[index] as UnaryExpression).Operator != UnaryOperator.None) && arguments[index].CodeNodeType != CodeNodeType.DynamicIndexerExpression && arguments[index].CodeNodeType != CodeNodeType.DynamicMemberReferenceExpression && !DynamicElementAnalyzer.Analyze(arguments[index])) { CastExpression theCastExpression = new CastExpression(arguments[index], objectTypeRef, null); theCastExpression.DynamicPositioningFlags = new bool[] { true }; arguments[index] = theCastExpression; } } }
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 (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 Expression GenerateSetMemberExpression(CallSiteInfo callSiteInfo, IList<Expression> arguments, IEnumerable<Instruction> instructions) { if (arguments.Count != 2) { throw new Exception("Invalid number of arguments for set index expression."); } return new BinaryExpression(BinaryOperator.Assign, new DynamicMemberReferenceExpression(arguments[0], callSiteInfo.MemberName, objectTypeRef, instructions), arguments[1], typeSystem, null); }
private Expression GenerateInvokeMemeberExpression(CallSiteInfo callSiteInfo, IList<Expression> arguments, IEnumerable<Instruction> instructions) { if (arguments.Count < 1) { throw new Exception("Invalid number of arguments for invoke expression."); } Expression target; TypeReference typeRef; if (arguments[0].CodeNodeType == CodeNodeType.MethodInvocationExpression && (arguments[0] as MethodInvocationExpression).IsTypeOfExpression(out typeRef)) { target = new TypeReferenceExpression(typeRef, arguments[0].UnderlyingSameMethodInstructions); } else { target = arguments[0]; } DynamicMemberReferenceExpression dynamicMemberReferenceExpression = new DynamicMemberReferenceExpression(target, callSiteInfo.MemberName, objectTypeRef, instructions, GetAllButFirst(arguments), callSiteInfo.GenericTypeArguments); return dynamicMemberReferenceExpression; }
private Expression GenerateInvokeExpression(CallSiteInfo callSiteInfo, IList<Expression> arguments, IEnumerable<Instruction> instructions) { return GenerateInvokeMemeberExpression(callSiteInfo, arguments, instructions); }
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 GetGenericTypeArgument(MethodInvocationExpression expression, int index, CallSiteInfo callSiteInfo) { TypeReference typeRef; if (!expression.IsTypeOfExpression(out typeRef)) { throw new Exception(InvalidStatementExceptionString); } callSiteInfo.GenericTypeArguments.Add(typeRef); }
private Expression GenerateConvertExpression(CallSiteInfo callSiteInfo, IList<Expression> arguments, IEnumerable<Instruction> instructions) { if (arguments.Count != 1) { throw new Exception("Invalid number of arguments for convert expression."); } return new CastExpression(arguments[0], callSiteInfo.ConvertType, instructions); }
private Expression GenerateUnaryExpression(CallSiteInfo callSiteInfo, IList<Expression> arguments, IEnumerable<Instruction> instructions) { if (arguments.Count != 1) { throw new Exception("Invalid number of arguments for unary expression."); } if (callSiteInfo.Operator != ExpressionType.IsTrue) { return new UnaryExpression(DynamicHelper.GetUnaryOperator(callSiteInfo.Operator), arguments[0], instructions); } else { return arguments[0]; } }
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 Expression GenerateExpression(CallSiteInfo callSiteInfo, IEnumerable <Expression> originalArguments, IEnumerable <Instruction> instructions) { V_0 = this.GetAllButFirst(originalArguments); this.MarkDynamicArguments(callSiteInfo, V_0); switch (callSiteInfo.get_BinderType()) { case 0: { return(this.GenerateBinaryExpression(callSiteInfo, V_0, instructions)); } case 1: { return(this.GenerateConvertExpression(callSiteInfo, V_0, instructions)); } case 2: { return(this.GenerateGetIndexExpression(V_0, instructions)); } case 3: { return(this.GenerateGetMemberExpression(callSiteInfo, V_0, instructions)); } case 4: { return(this.GenerateInvokeExpression(callSiteInfo, V_0, instructions)); } case 5: { return(this.GenerateInvokeConstructorExpression(V_0, instructions)); } case 6: { return(this.GenerateInvokeMemeberExpression(callSiteInfo, V_0, instructions)); } case 7: { Label0: throw new Exception("Invalid binder type."); } case 8: { return(this.GenerateSetIndexExpression(V_0, instructions)); } case 9: { return(this.GenerateSetMemberExpression(callSiteInfo, V_0, instructions)); } case 10: { return(this.GenerateUnaryExpression(callSiteInfo, V_0, instructions)); } default: { goto Label0; } } }
private Expression GenerateExpression(CallSiteInfo callSiteInfo, IEnumerable<Expression> originalArguments, IEnumerable<Instruction> instructions) { IList<Expression> arguments = GetAllButFirst(originalArguments); MarkDynamicArguments(callSiteInfo, arguments); switch (callSiteInfo.BinderType) { case CallSiteBinderType.BinaryOperation: return GenerateBinaryExpression(callSiteInfo, arguments, instructions); case CallSiteBinderType.Convert: return GenerateConvertExpression(callSiteInfo, arguments, instructions); case CallSiteBinderType.GetIndex: return GenerateGetIndexExpression(arguments, instructions); case CallSiteBinderType.GetMember: return GenerateGetMemberExpression(callSiteInfo, arguments, instructions); case CallSiteBinderType.Invoke: return GenerateInvokeExpression(callSiteInfo, arguments, instructions); case CallSiteBinderType.InvokeConstructor: return GenerateInvokeConstructorExpression(arguments, instructions); case CallSiteBinderType.InvokeMember: return GenerateInvokeMemeberExpression(callSiteInfo, arguments, instructions); case CallSiteBinderType.SetIndex: return GenerateSetIndexExpression(arguments, instructions); case CallSiteBinderType.SetMember: return GenerateSetMemberExpression(callSiteInfo, arguments, instructions); case CallSiteBinderType.UnaryOperation: return GenerateUnaryExpression(callSiteInfo, arguments, instructions); } throw new Exception("Invalid binder type."); }