private static IEnumerable <ReflectionFunctionBinding> CreateBindingsFromContainer(object container) { List <ReflectionFunctionBinding> bindings = new List <ReflectionFunctionBinding>(); foreach (MethodInfo methodInfo in container.GetType().GetMethods()) { object instance; if (methodInfo.IsStatic) { instance = null; } else { instance = container; } FunctionBindingAttribute[] functionBindingAttributes = (FunctionBindingAttribute[])methodInfo.GetCustomAttributes(typeof(FunctionBindingAttribute), false); if (functionBindingAttributes.Length == 1) { string functionName = functionBindingAttributes[0].Name; bool isDeterministic = functionBindingAttributes[0].IsDeterministic; ReflectionFunctionBinding reflectionFunctionBinding = new ReflectionFunctionBinding(functionName, methodInfo, instance, isDeterministic); bindings.Add(reflectionFunctionBinding); } } return(bindings); }
private void RemoveFromContainer(IEnumerable <ReflectionFunctionBinding> containerBindings) { List <FunctionBinding> bindigsToRemove = new List <FunctionBinding>(); foreach (FunctionBinding functionBinding in this) { ReflectionFunctionBinding reflectionFunctionBinding = functionBinding as ReflectionFunctionBinding; if (reflectionFunctionBinding != null) { foreach (ReflectionFunctionBinding containerBinding in containerBindings) { if (reflectionFunctionBinding.Method == containerBinding.Method) { bindigsToRemove.Add(functionBinding); break; } } } } foreach (FunctionBinding binding in bindigsToRemove) { Remove(binding); } }
public FunctionBinding Add(string functionName, Delegate functionDelegate) { if (functionName == null) { throw ExceptionBuilder.ArgumentNull("functionName"); } if (functionDelegate == null) { throw ExceptionBuilder.ArgumentNull("functionDelegate"); } // Check return type if (functionDelegate.Method.ReturnType == typeof(void)) { throw ExceptionBuilder.FunctionMustNotBeVoid(functionDelegate); } // Check parameters ParameterInfo[] parameters = functionDelegate.Method.GetParameters(); foreach (ParameterInfo param in parameters) { if (param.IsOut || param.ParameterType.IsByRef) { throw ExceptionBuilder.FunctionMustNotHaveRefOrOutParams(functionDelegate, param); } if (param.IsOptional) { throw ExceptionBuilder.FunctionMustNotHaveOptionalParams(functionDelegate, param); } if (param.ParameterType.IsArray) { throw ExceptionBuilder.FunctionMustNotHaveArrayParams(functionDelegate, param); } } // Ok, everything seems to be fine. ReflectionFunctionBinding reflectionFunctionBinding = new ReflectionFunctionBinding(functionName, functionDelegate.Method, functionDelegate.Target, false); Add(reflectionFunctionBinding); return(reflectionFunctionBinding); }
public override ExpressionNode VisitFunctionInvocationExpression(FunctionInvocationExpression expression) { base.VisitFunctionInvocationExpression(expression); ReflectionFunctionBinding reflectionFunctionBinding = expression.Function as ReflectionFunctionBinding; if (reflectionFunctionBinding != null) { if (reflectionFunctionBinding.Instance != null) { _ilEmitContext.AddParameter(expression, reflectionFunctionBinding.Instance, reflectionFunctionBinding.Instance.GetType()); } } else { _ilEmitContext.AddParameter(expression, expression.Function, typeof(FunctionBinding)); object[] args = new object[expression.Arguments.Length]; _ilEmitContext.AddParameter(expression, args, typeof(object[])); } return(expression); }
public override ExpressionNode VisitFunctionInvocationExpression(FunctionInvocationExpression expression) { ReflectionFunctionBinding reflectionFunctionBinding = expression.Function as ReflectionFunctionBinding; if (reflectionFunctionBinding != null) { MethodInfo method = reflectionFunctionBinding.Method; ParameterInfo[] parameterInfos = method.GetParameters(); ILParameterDeclaration instance; if (reflectionFunctionBinding.Instance != null) { instance = _ilEmitContext.GetParameters(expression)[0]; } else { instance = null; } int[] argLocalIndexes = new int[expression.Arguments.Length]; for (int i = 0; i < expression.Arguments.Length; i++) { argLocalIndexes[i] = DeclareLocal(); } for (int i = 0; i < expression.Arguments.Length; i++) { Visit(expression.Arguments[i]); _ilEmitContext.ILGenerator.Emit(OpCodes.Stloc, argLocalIndexes[i]); } Label loadNullLabel = _ilEmitContext.ILGenerator.DefineLabel(); Label finishLabel = _ilEmitContext.ILGenerator.DefineLabel(); for (int i = 0; i < expression.Arguments.Length; i++) { _ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, argLocalIndexes[i]); _ilEmitContext.ILGenerator.Emit(OpCodes.Brfalse, loadNullLabel); } if (instance != null) { EmitLoadParameter(instance); EmitThisArgumentPointer(instance.Type); } for (int i = 0; i < expression.Arguments.Length; i++) { _ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, argLocalIndexes[i]); if (parameterInfos[i].ParameterType != typeof(object)) { EmitConversion(parameterInfos[i].ParameterType); } } EmitRawCall(method, instance == null ? null : instance.Type); if (method.ReturnType.IsValueType) { _ilEmitContext.ILGenerator.Emit(OpCodes.Box, method.ReturnType); } _ilEmitContext.ILGenerator.EmitCall(OpCodes.Call, _unifyNullsMethod, null); _ilEmitContext.ILGenerator.Emit(OpCodes.Br, finishLabel); _ilEmitContext.ILGenerator.MarkLabel(loadNullLabel); _ilEmitContext.ILGenerator.Emit(OpCodes.Ldnull); _ilEmitContext.ILGenerator.MarkLabel(finishLabel); } else { int[] argLocalIndexes = new int[expression.Arguments.Length]; for (int i = 0; i < expression.Arguments.Length; i++) { argLocalIndexes[i] = DeclareLocal(); } for (int i = 0; i < expression.Arguments.Length; i++) { Visit(expression.Arguments[i]); _ilEmitContext.ILGenerator.Emit(OpCodes.Stloc, argLocalIndexes[i]); } Label loadNullLabel = _ilEmitContext.ILGenerator.DefineLabel(); Label finishLabel = _ilEmitContext.ILGenerator.DefineLabel(); for (int i = 0; i < expression.Arguments.Length; i++) { _ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, argLocalIndexes[i]); _ilEmitContext.ILGenerator.Emit(OpCodes.Brfalse, loadNullLabel); } ILParameterDeclaration customFunctionBinding = _ilEmitContext.GetParameters(expression)[0]; ILParameterDeclaration argsArray = _ilEmitContext.GetParameters(expression)[1]; int argsArrayIndex = DeclareLocal(); EmitLoadParameter(argsArray); _ilEmitContext.ILGenerator.Emit(OpCodes.Stloc, argsArrayIndex); for (int i = 0; i < expression.Arguments.Length; i++) { _ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, argsArrayIndex); _ilEmitContext.ILGenerator.Emit(OpCodes.Ldc_I4, i); _ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, argLocalIndexes[i]); _ilEmitContext.ILGenerator.Emit(OpCodes.Stelem_Ref); } EmitLoadParameter(customFunctionBinding); EmitThisArgumentPointer(typeof(FunctionBinding)); _ilEmitContext.ILGenerator.Emit(OpCodes.Ldloc, argsArrayIndex); _ilEmitContext.ILGenerator.EmitCall(OpCodes.Callvirt, _functionBindingInvokeMethod, null); _ilEmitContext.ILGenerator.EmitCall(OpCodes.Call, _unifyNullsMethod, null); _ilEmitContext.ILGenerator.Emit(OpCodes.Br, finishLabel); _ilEmitContext.ILGenerator.MarkLabel(loadNullLabel); _ilEmitContext.ILGenerator.Emit(OpCodes.Ldnull); _ilEmitContext.ILGenerator.MarkLabel(finishLabel); } return(expression); }