Ejemplo n.º 1
0
        private static MondInstanceFunction BindInstanceImpl(string className, MethodTable method, string nameOverride = null, bool fakeInstance = false)
        {
            var errorPrefix = BindingError.ErrorPrefix(className, nameOverride ?? method.Name);

            if (!fakeInstance)
            {
                return((state, instance, args) =>
                {
                    MethodBase function;
                    ReturnConverter returnConversion;
                    var parameters = BuildParameterArray(errorPrefix, method, state, instance, args, out function, out returnConversion);

                    var classInstance = instance.UserData;

                    if (ReferenceEquals(classInstance, null))
                    {
                        throw new MondRuntimeException(errorPrefix + BindingError.RequiresInstance);
                    }

                    return returnConversion(errorPrefix, state, Call(() => function.Invoke(classInstance, parameters)));
                });
            }

            return((state, instance, args) =>
            {
                MethodBase function;
                ReturnConverter returnConversion;
                var parameters = BuildParameterArray(errorPrefix, method, state, instance, args, out function, out returnConversion);

                return returnConversion(errorPrefix, state, Call(() => function.Invoke(null, parameters)));
            });
        }
Ejemplo n.º 2
0
        private static TFunc BindImpl <TFunc, TReturn>(
            string moduleName,
            MethodTable methodTable,
            bool instanceFunction,
            BindCallFactory callFactory)
        {
            var errorPrefix = BindingError.ErrorPrefix(moduleName, methodTable.Name);

            var parameters = new List <ParameterExpression>
            {
                Expression.Parameter(typeof(MondState), "state"),
                Expression.Parameter(typeof(MondValue[]), "arguments")
            };

            if (instanceFunction)
            {
                parameters.Insert(1, Expression.Parameter(typeof(MondValue), "instance"));
            }

            var argumentsParam = parameters[instanceFunction ? 2 : 1];

            var statements  = new List <Expression>();
            var returnLabel = Expression.Label(typeof(TReturn));

            var argumentsLength = Expression.PropertyOrField(argumentsParam, "Length");

            for (var i = 0; i < methodTable.Methods.Count; i++)
            {
                var dispatches = BuildDispatchExpression(errorPrefix, methodTable.Methods[i], i, parameters, instanceFunction, returnLabel, callFactory);

                if (dispatches.Count == 0)
                {
                    continue;
                }

                var requiredArgCount = Expression.Constant(i);
                var argLengthEqual   = Expression.Equal(argumentsLength, requiredArgCount);
                var argBranch        = Expression.IfThen(argLengthEqual, Expression.Block(dispatches));

                statements.Add(argBranch);
            }

            foreach (var group in methodTable.ParamsMethods.GroupBy(p => p.RequiredMondParameterCount))
            {
                var dispatches       = BuildDispatchExpression(errorPrefix, group, int.MaxValue, parameters, instanceFunction, returnLabel, callFactory);
                var requiredArgCount = Expression.Constant(group.Key);
                var argLengthAtLeast = Expression.GreaterThanOrEqual(argumentsLength, requiredArgCount);
                var argBranch        = Expression.IfThen(argLengthAtLeast, Expression.Block(dispatches));

                statements.Add(argBranch);
            }

            statements.Add(ThrowParameterTypeError(errorPrefix, methodTable));

            statements.Add(Expression.Label(returnLabel, Expression.Default(typeof(TReturn))));

            var block = Expression.Block(statements);

            return(Expression.Lambda <TFunc>(block, parameters).Compile());
        }
Ejemplo n.º 3
0
        private static MondConstructor BindConstructorImpl(string moduleName, MethodTable method)
        {
            var errorPrefix = BindingError.ErrorPrefix(moduleName, "#ctor");

            return((state, instance, args) =>
            {
                MethodBase constructor;
                ReturnConverter returnConversion;
                var parameters = BuildParameterArray(errorPrefix, method, state, instance, args, out constructor, out returnConversion);

                return Call(() => ((ConstructorInfo)constructor).Invoke(parameters));
            });
        }
Ejemplo n.º 4
0
        private static MondFunction BindImpl(string moduleName, MethodTable method, string nameOverride = null)
        {
            var errorPrefix = BindingError.ErrorPrefix(moduleName, nameOverride ?? method.Name);

            return((state, args) =>
            {
                MethodBase function;
                ReturnConverter returnConversion;
                var parameters = BuildParameterArray(errorPrefix, method, state, null, args, out function, out returnConversion);

                return returnConversion(errorPrefix, state, Call(() => function.Invoke(null, parameters)));
            });
        }