Ejemplo n.º 1
0
        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);
        }
Ejemplo n.º 2
0
        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);
            }
        }
Ejemplo n.º 3
0
        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);
        }
Ejemplo n.º 4
0
        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);
        }
Ejemplo n.º 5
0
        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);
        }