/// <summary> /// Generate IL for member init expression /// </summary> /// <param name="request">request</param> /// <param name="expression">expression</param> /// <returns></returns> public bool GenerateIL(DynamicMethodGenerationRequest request, MemberInitExpression expression) { if (!request.TryGenerateIL(request, expression.NewExpression)) { return(false); } var instance = request.ILGenerator.DeclareLocal(expression.Type); request.ILGenerator.Emit(OpCodes.Stloc, instance); foreach (var binding in expression.Bindings) { if (binding.BindingType != MemberBindingType.Assignment) { return(false); } request.ILGenerator.Emit(OpCodes.Ldloc, instance); if (!request.TryGenerateIL(request, ((MemberAssignment)binding).Expression)) { return(false); } var propertyInfo = binding.Member as PropertyInfo; if (propertyInfo != null) { var setMethod = propertyInfo.SetMethod; if (setMethod == null) { return(false); } request.ILGenerator.EmitMethodCall(setMethod); } else if (binding.Member is FieldInfo) { request.ILGenerator.Emit(OpCodes.Stfld, (FieldInfo)binding.Member); } else { return(false); } } request.ILGenerator.Emit(OpCodes.Ldloc, instance); return(true); }
/// <summary> /// Generate IL for method call expression /// </summary> /// <param name="request">dynamic method request</param> /// <param name="expression">expression to convert</param> /// <returns></returns> public bool GenerateIL(DynamicMethodGenerationRequest request, MethodCallExpression expression) { if (!request.TryGenerateIL(request, expression.Object)) { return(false); } if (expression.Arguments.Any(expressionArgument => !request.TryGenerateIL(request, expressionArgument))) { return(false); } request.ILGenerator.EmitMethodCall(expression.Method); return(true); }
/// <summary> /// Generate IL for new expression /// </summary> /// <param name="request">request</param> /// <param name="expression">expression</param> /// <returns></returns> public bool GenerateIL(DynamicMethodGenerationRequest request, NewExpression expression) { if (expression.Arguments.Any(argument => !request.TryGenerateIL(request, argument))) { return(false); } request.ILGenerator.Emit(OpCodes.Newobj, expression.Constructor); return(true); }
/// <summary> /// Generate IL for new array expression /// </summary> /// <param name="request">request for generation</param> /// <param name="expression">expression to convert</param> /// <returns></returns> public bool GenerateIL(DynamicMethodGenerationRequest request, NewArrayExpression expression) { var arrayType = expression.Type; var elementType = arrayType.GetElementType(); var elementIsValueType = elementType.GetTypeInfo().IsValueType; var arrayInstance = request.ILGenerator.DeclareLocal(arrayType); request.ILGenerator.EmitInt(expression.Expressions.Count); request.ILGenerator.Emit(OpCodes.Newarr, elementType); request.ILGenerator.Emit(OpCodes.Stloc, arrayInstance); var index = 0; foreach (var instanceExpression in expression.Expressions) { request.ILGenerator.Emit(OpCodes.Ldloc, arrayInstance); request.ILGenerator.EmitInt(index); index++; if (elementIsValueType) { request.ILGenerator.Emit(OpCodes.Ldelema, elementType); } if (!request.TryGenerateIL(request, instanceExpression)) { return(false); } if (elementIsValueType) { request.ILGenerator.Emit(OpCodes.Stobj, elementType); } else { request.ILGenerator.Emit(OpCodes.Stelem_Ref); } } request.ILGenerator.Emit(OpCodes.Ldloc, arrayInstance); return(true); }
/// <summary> /// Generate IL for assign statement /// </summary> /// <param name="request"></param> /// <param name="expression"></param> /// <returns></returns> public bool GenerateIL(DynamicMethodGenerationRequest request, BinaryExpression expression) { if (request.TryGenerateIL(request, expression.Right)) { for (int i = 0; i < request.ExtraParameters.Length; i++) { if (expression.Left == request.ExtraParameters[i]) { switch (i) { case 0: request.ILGenerator.Emit(OpCodes.Stloc_0); return(true); case 1: request.ILGenerator.Emit(OpCodes.Stloc_1); return(true); case 2: request.ILGenerator.Emit(OpCodes.Stloc_2); return(true); case 3: request.ILGenerator.Emit(OpCodes.Stloc_3); return(true); default: request.ILGenerator.Emit(OpCodes.Stloc_S, i); return(true); } } } } return(false); }