public MethodInvocationExpression GetCallbackMethodInvocation(AbstractTypeEmitter invocation, Expression[] args, Reference targetField, MethodEmitter invokeMethodOnTarget) { var allArgs = GetAllArgs(args, targetField); var @delegate = (Reference)invocation.GetField("delegate"); return new MethodInvocationExpression(@delegate, GetCallbackMethod(), allArgs); }
public Expression[] GetConstructorInvocationArguments(Expression[] arguments, ClassEmitter proxy) { var allArguments = new Expression[arguments.Length + 1]; allArguments[0] = new ReferenceExpression(BuildDelegateToken(proxy)); Array.Copy(arguments, 0, allArguments, 1, arguments.Length); return allArguments; }
public MethodInvocationExpression GetCallbackMethodInvocation(AbstractTypeEmitter invocation, Expression[] args, Reference targetField, MethodEmitter invokeMethodOnTarget) { var @delegate = GetDelegate(invocation, invokeMethodOnTarget); return new MethodInvocationExpression(@delegate, GetCallbackMethod(), args); }
public static Expression[] ConvertArgumentReferenceToExpression(ArgumentReference[] args) { var expressions = new Expression[args.Length]; for (var i = 0; i < args.Length; ++i) { expressions[i] = args[i].ToExpression(); } return expressions; }
public BindDelegateExpression(Type @delegate, Expression owner, MethodInfo methodToBindTo, GenericTypeParameterBuilder[] genericTypeParams) { delegateCtor = @delegate.GetConstructors()[0]; this.methodToBindTo = methodToBindTo; if(@delegate.IsGenericTypeDefinition) { var closedDelegate = @delegate.MakeGenericType(genericTypeParams); delegateCtor = TypeBuilder.GetConstructor(closedDelegate, delegateCtor); this.methodToBindTo = methodToBindTo.MakeGenericMethod(genericTypeParams); } this.owner = owner; }
public NullCoalescingOperatorExpression(Expression expression, Expression @default) { if (expression == null) { throw new ArgumentNullException("expression"); } if (@default == null) { throw new ArgumentNullException("default"); } this.expression = expression; this.@default = @default; }
private Expression[] GetCtorArguments(ClassEmitter @class, Expression proxiedMethodTokenExpression, TypeReference[] dereferencedArguments, Expression methodInterceptors) { return new[] { getTargetExpression(@class, MethodToOverride), SelfReference.Self.ToExpression(), methodInterceptors ?? interceptors.ToExpression(), proxiedMethodTokenExpression, new ReferencesToObjectArrayExpression(dereferencedArguments) }; }
public ConvertExpression(Type targetType, Type fromType, Expression right) { target = targetType; this.fromType = fromType; this.right = right; }
public ConvertExpression(Type targetType, Expression right) : this(targetType, typeof(object), right) { }
public AssignArgumentStatement(ArgumentReference argument, Expression expression) { this.argument = argument; this.expression = expression; }
public AssignArrayStatement(Reference targetArray, int targetPosition, Expression value) { this.targetArray = targetArray; this.targetPosition = targetPosition; this.value = value; }
protected void CreateIInvocationInvokeOnTarget( ClassEmitter targetTypeEmitter, NestedClassEmitter nested, ParameterInfo[] parameters, FieldReference targetField, MethodInfo callbackMethod) { const MethodAttributes methodAtts = MethodAttributes.Public | MethodAttributes.Final | MethodAttributes.Virtual; MethodEmitter method = nested.CreateMethod ("InvokeMethodOnTarget", methodAtts, typeof (void)); Expression[] args = new Expression[parameters.Length]; // Idea: instead of grab parameters one by one // we should grab an array Hashtable byRefArguments = new Hashtable(); for(int i = 0; i < parameters.Length; i++) { ParameterInfo param = parameters[i]; Type paramType = param.ParameterType; if (HasGenericParameters(paramType)) { paramType = paramType.GetGenericTypeDefinition().MakeGenericType(nested.GetGenericArgumentsFor(paramType)); } else if (paramType.IsGenericParameter) { paramType = nested.GetGenericArgument(paramType.Name); } if (paramType.IsByRef) { LocalReference localReference = method.CodeBuilder.DeclareLocal(paramType.GetElementType()); method.CodeBuilder.AddStatement( new AssignStatement(localReference, new ConvertExpression(paramType.GetElementType(), new MethodInvocationExpression(SelfReference.Self, typeof(AbstractInvocation).GetMethod( "GetArgumentValue"), new LiteralIntExpression(i))))); ByRefReference byRefReference = new ByRefReference(localReference); args[i] = new ReferenceExpression(byRefReference); byRefArguments[i] = localReference; } else { args[i] = new ConvertExpression(paramType, new MethodInvocationExpression(SelfReference.Self, typeof(AbstractInvocation).GetMethod("GetArgumentValue"), new LiteralIntExpression(i))); } } MethodInvocationExpression baseMethodInvExp; if (callbackMethod.IsGenericMethod) { callbackMethod = callbackMethod.MakeGenericMethod(nested.GetGenericArgumentsFor(callbackMethod)); } baseMethodInvExp = new MethodInvocationExpression(targetField, callbackMethod, args); baseMethodInvExp.VirtualCall = true; LocalReference ret_local = null; if (callbackMethod.ReturnType != typeof(void)) { if (callbackMethod.ReturnType.IsGenericParameter) { ret_local = method.CodeBuilder.DeclareLocal(nested.GetGenericArgument(callbackMethod.ReturnType.Name)); } else if (HasGenericParameters(callbackMethod.ReturnType)) { ret_local = method.CodeBuilder.DeclareLocal( callbackMethod.ReturnType.GetGenericTypeDefinition().MakeGenericType( nested.GetGenericArgumentsFor(callbackMethod.ReturnType))); } else { ret_local = method.CodeBuilder.DeclareLocal(callbackMethod.ReturnType); } method.CodeBuilder.AddStatement(new AssignStatement(ret_local, baseMethodInvExp)); } else { method.CodeBuilder.AddStatement(new ExpressionStatement(baseMethodInvExp)); } foreach(DictionaryEntry byRefArgument in byRefArguments) { int index = (int) byRefArgument.Key; LocalReference localReference = (LocalReference) byRefArgument.Value; method.CodeBuilder.AddStatement( new ExpressionStatement( new MethodInvocationExpression(SelfReference.Self, typeof(AbstractInvocation).GetMethod("SetArgumentValue"), new LiteralIntExpression(index), new ConvertExpression(typeof(object), localReference.Type, new ReferenceExpression(localReference))) )); } if (callbackMethod.ReturnType != typeof(void)) { MethodInvocationExpression setRetVal = new MethodInvocationExpression(SelfReference.Self, typeof(AbstractInvocation).GetMethod("set_ReturnValue"), new ConvertExpression(typeof(object), ret_local.Type, ret_local.ToExpression())); method.CodeBuilder.AddStatement(new ExpressionStatement(setRetVal)); } method.CodeBuilder.AddStatement(new ReturnStatement()); }
private MethodBuilder CreateCallbackMethod(ClassEmitter emitter, MethodInfo methodInfo, MethodInfo methodOnTarget) { var targetMethod = methodOnTarget ?? methodInfo; var callBackMethod = emitter.CreateMethod(namingScope.GetUniqueName(methodInfo.Name + "_callback"), targetMethod); if (targetMethod.IsGenericMethod) targetMethod = targetMethod.MakeGenericMethod(callBackMethod.GenericTypeParams); var exps = new Expression[callBackMethod.Arguments.Length]; for (var i = 0; i < callBackMethod.Arguments.Length; i++) { exps[i] = callBackMethod.Arguments[i].ToExpression(); } // invocation on base class callBackMethod.CodeBuilder.AddStatement( new ReturnStatement( new MethodInvocationExpression(SelfReference.Self, targetMethod, exps))); return callBackMethod.MethodBuilder; }
public AssignStatement(Reference target, Expression expression) { this.target = target; this.expression = expression; }
public AbstractCodeBuilder AddExpression(Expression expression) { return AddStatement(new ExpressionStatement(expression)); }
public void AddExpression(Expression expression) { AddStatement(new ExpressionStatement(expression)); }
private Expression[] ModifyArguments(ClassEmitter @class, Expression[] arguments) { if (contributor == null) { return arguments; } return contributor.GetConstructorInvocationArguments(arguments, @class); }
private Expression[] GetAllArgs(Expression[] args, Reference targetField) { var allArgs = new Expression[args.Length + 1]; args.CopyTo(allArgs, 1); allArgs[0] = new ConvertExpression(targetType, targetField.ToExpression()); return allArgs; }
private Expression SetMethodInterceptors(ClassEmitter @class, INamingScope namingScope, MethodEmitter emitter, Expression proxiedMethodTokenExpression) { var selector = @class.GetField("__selector"); if(selector == null) { return null; } var methodInterceptorsField = BuildMethodInterceptorsField(@class, MethodToOverride, namingScope); var emptyInterceptors = new NewArrayExpression(0, typeof(IInterceptor)); var selectInterceptors = new MethodInvocationExpression(selector, InterceptorSelectorMethods.SelectInterceptors, new MethodInvocationExpression(null, TypeUtilMethods.GetTypeOrNull, getTargetExpression(@class, MethodToOverride)), proxiedMethodTokenExpression, interceptors.ToExpression()) { VirtualCall = true }; emitter.CodeBuilder.AddExpression( new IfNullExpression(methodInterceptorsField, new AssignStatement(methodInterceptorsField, new NullCoalescingOperatorExpression(selectInterceptors, emptyInterceptors)))); return methodInterceptorsField.ToExpression(); }
private Expression[] GetCtorArguments(ClassEmitter @class, INamingScope namingScope, Expression proxiedMethodTokenExpression, TypeReference[] dereferencedArguments) { var selector = @class.GetField("__selector"); if (selector != null) { return new[] { getTargetExpression(@class, MethodToOverride), SelfReference.Self.ToExpression(), interceptors.ToExpression(), proxiedMethodTokenExpression, new ReferencesToObjectArrayExpression(dereferencedArguments), selector.ToExpression(), new AddressOfReferenceExpression(BuildMethodInterceptorsField(@class, MethodToOverride, namingScope)) }; } return new[] { getTargetExpression(@class, MethodToOverride), SelfReference.Self.ToExpression(), interceptors.ToExpression(), proxiedMethodTokenExpression, new ReferencesToObjectArrayExpression(dereferencedArguments) }; }
protected MethodBuilder CreateCallbackMethod(ClassEmitter emitter, MethodInfo methodInfo, MethodInfo methodOnTarget) { MethodInfo targetMethod = methodOnTarget != null ? methodOnTarget : methodInfo; if (targetMethod.IsAbstract) return null; // MethodBuild creation MethodAttributes atts = MethodAttributes.Family; String name = methodInfo.Name + "_callback_" + ++callbackCounter; MethodEmitter callBackMethod = emitter.CreateMethod(name, atts); callBackMethod.CopyParametersAndReturnTypeFrom(targetMethod, emitter); // Generic definition if (targetMethod.IsGenericMethod) { targetMethod = targetMethod.MakeGenericMethod(callBackMethod.GenericTypeParams); } // Parameters exp Expression[] exps = new Expression[callBackMethod.Arguments.Length]; for(int i = 0; i < callBackMethod.Arguments.Length; i++) { exps[i] = callBackMethod.Arguments[i].ToExpression(); } // invocation on base class callBackMethod.CodeBuilder.AddStatement( new ReturnStatement(new MethodInvocationExpression(GetProxyTargetReference(), targetMethod, exps))); return callBackMethod.MethodBuilder; }
public ExpressionStatement(Expression expression) { this.expression = expression; }
public Expression[] GetConstructorInvocationArguments(Expression[] arguments, ClassEmitter proxy) { return arguments; }
public IfNullExpression(Reference reference, Expression ifNull, Expression ifNotNull) { this.reference = reference; this.ifNull = ifNull; this.ifNotNull = ifNotNull; }
private MethodBuilder CreateCallbackMethod(ClassEmitter emitter, MethodInfo methodInfo, MethodInfo methodOnTarget) { MethodInfo targetMethod = methodOnTarget ?? methodInfo; // MethodBuild creation MethodEmitter callBackMethod = emitter.CreateMethod(namingScope.GetUniqueName(methodInfo.Name + "_callback")); callBackMethod.CopyParametersAndReturnTypeFrom(targetMethod, emitter); // Generic definition if (targetMethod.IsGenericMethod) { targetMethod = targetMethod.MakeGenericMethod(callBackMethod.GenericTypeParams); } // Parameters exp Expression[] exps = new Expression[callBackMethod.Arguments.Length]; for (int i = 0; i < callBackMethod.Arguments.Length; i++) { exps[i] = callBackMethod.Arguments[i].ToExpression(); } // invocation on base class callBackMethod.CodeBuilder.AddStatement( new ReturnStatement(new MethodInvocationExpression(SelfReference.Self, targetMethod, exps))); return callBackMethod.MethodBuilder; }