コード例 #1
0
ファイル: MethodCandidate.cs プロジェクト: rudimk/dlr-dotnet
        internal Expression MakeExpression(RestrictedArguments restrictedArgs)
        {
            bool[]       usageMarkers;
            Expression[] spilledArgs;
            Expression[] callArgs = GetArgumentExpressions(restrictedArgs, out usageMarkers, out spilledArgs);

            Expression call;
            MethodBase mb = _overload.ReflectionInfo;

            // TODO: make MakeExpression virtual on OverloadInfo?
            if (mb == null)
            {
                throw new InvalidOperationException("Cannot generate an expression for an overload w/o MethodBase");
            }

            MethodInfo mi = mb as MethodInfo;

            if (mi != null)
            {
                Expression instance;
                if (mi.IsStatic)
                {
                    instance = null;
                }
                else
                {
                    Debug.Assert(mi != null);
                    instance = _instanceBuilder.ToExpression(ref mi, _resolver, restrictedArgs, usageMarkers);
                    Debug.Assert(instance != null, "Can't skip instance expression");
                }

                if (CompilerHelpers.IsVisible(mi))
                {
                    call = AstUtils.SimpleCallHelper(instance, mi, callArgs);
                }
                else
                {
                    call = Ast.Call(
                        typeof(BinderOps).GetMethod("InvokeMethod"),
                        AstUtils.Constant(mi),
                        instance != null ? AstUtils.Convert(instance, typeof(object)) : AstUtils.Constant(null),
                        AstUtils.NewArrayHelper(typeof(object), callArgs)
                        );
                }
            }
            else
            {
                ConstructorInfo ci = (ConstructorInfo)mb;
                if (CompilerHelpers.IsVisible(ci))
                {
                    call = AstUtils.SimpleNewHelper(ci, callArgs);
                }
                else
                {
                    call = Ast.Call(
                        typeof(BinderOps).GetMethod("InvokeConstructor"),
                        AstUtils.Constant(ci),
                        AstUtils.NewArrayHelper(typeof(object), callArgs)
                        );
                }
            }

            if (spilledArgs != null)
            {
                call = Expression.Block(spilledArgs.AddLast(call));
            }

            Expression ret = _returnBuilder.ToExpression(_resolver, _argBuilders, restrictedArgs, call);

            List <Expression> updates = null;

            for (int i = 0; i < _argBuilders.Count; i++)
            {
                Expression next = _argBuilders[i].UpdateFromReturn(_resolver, restrictedArgs);
                if (next != null)
                {
                    if (updates == null)
                    {
                        updates = new List <Expression>();
                    }
                    updates.Add(next);
                }
            }

            if (updates != null)
            {
                if (ret.Type != typeof(void))
                {
                    ParameterExpression temp = Ast.Variable(ret.Type, "$ret");
                    updates.Insert(0, Ast.Assign(temp, ret));
                    updates.Add(temp);
                    ret = Ast.Block(new[] { temp }, updates.ToArray());
                }
                else
                {
                    updates.Insert(0, ret);
                    ret = Ast.Block(typeof(void), updates.ToArray());
                }
            }

            if (_resolver.Temps != null)
            {
                ret = Ast.Block(_resolver.Temps, ret);
            }

            return(ret);
        }
コード例 #2
0
        internal override Expression ToExpression(ParameterBinder parameterBinder, IList <ArgBuilder> args, IList <Expression> parameters, Expression ret)
        {
            List <Expression> sets = new List <Expression>();

            ParameterExpression tmp = parameterBinder.GetTemporary(ret.Type, "val");

            sets.Add(
                Ast.Assign(tmp, ret)
                );

            for (int i = 0; i < _indexesUsed.Length; i++)
            {
                Expression value = parameters[parameters.Count - _kwArgCount + _indexesUsed[i]];
                switch (_membersSet[i].MemberType)
                {
                case MemberTypes.Field:
                    FieldInfo fi = (FieldInfo)_membersSet[i];
                    if (!fi.IsLiteral && !fi.IsInitOnly)
                    {
                        sets.Add(
                            Ast.Assign(
                                Ast.Field(tmp, fi),
                                ConvertToHelper(parameterBinder, value, fi.FieldType)
                                )
                            );
                    }
                    else
                    {
                        // call a helper which throws the error but "returns object"
                        sets.Add(
                            Ast.Convert(
                                Ast.Call(
                                    typeof(ScriptingRuntimeHelpers).GetMethod("ReadOnlyAssignError"),
                                    Ast.Constant(true),
                                    Ast.Constant(fi.Name)
                                    ),
                                fi.FieldType
                                )
                            );
                    }
                    break;

                case MemberTypes.Property:
                    PropertyInfo pi = (PropertyInfo)_membersSet[i];
                    if (pi.GetSetMethod(_privateBinding) != null)
                    {
                        sets.Add(
                            Ast.Assign(
                                Ast.Property(tmp, pi),
                                ConvertToHelper(parameterBinder, value, pi.PropertyType)
                                )
                            );
                    }
                    else
                    {
                        // call a helper which throws the error but "returns object"
                        sets.Add(
                            Ast.Convert(
                                Ast.Call(
                                    typeof(ScriptingRuntimeHelpers).GetMethod("ReadOnlyAssignError"),
                                    Ast.Constant(false),
                                    Ast.Constant(pi.Name)
                                    ),
                                pi.PropertyType
                                )
                            );
                    }
                    break;
                }
            }

            sets.Add(
                tmp
                );

            Expression newCall = Ast.Block(
                sets.ToArray()
                );

            return(_builder.ToExpression(parameterBinder, args, parameters, newCall));
        }
コード例 #3
0
        internal override Expression ToExpression(OverloadResolver resolver, IList <ArgBuilder> builders, RestrictedArguments args, Expression ret)
        {
            List <Expression> sets = new List <Expression>();

            ParameterExpression tmp = resolver.GetTemporary(ret.Type, "val");

            sets.Add(
                Ast.Assign(tmp, ret)
                );

            for (int i = 0; i < _indexesUsed.Length; i++)
            {
                Expression value = args.GetObject(args.Length - _kwArgCount + _indexesUsed[i]).Expression;

                PropertyInfo pi;
                FieldInfo    fi;
                if ((fi = _membersSet[i] as FieldInfo) != null)
                {
                    if (!fi.IsLiteral && !fi.IsInitOnly)
                    {
                        sets.Add(
                            Ast.Assign(
                                Ast.Field(tmp, fi),
                                ConvertToHelper(resolver, value, fi.FieldType)
                                )
                            );
                    }
                    else
                    {
                        // call a helper which throws the error but "returns object"
                        sets.Add(
                            Ast.Convert(
                                Ast.Call(
                                    typeof(ScriptingRuntimeHelpers).GetMethod("ReadOnlyAssignError"),
                                    AstUtils.Constant(true),
                                    AstUtils.Constant(fi.Name)
                                    ),
                                fi.FieldType
                                )
                            );
                    }
                }
                else if ((pi = _membersSet[i] as PropertyInfo) != null)
                {
                    if (pi.GetSetMethod(_privateBinding) != null)
                    {
                        sets.Add(
                            Ast.Assign(
                                Ast.Property(tmp, pi),
                                ConvertToHelper(resolver, value, pi.PropertyType)
                                )
                            );
                    }
                    else
                    {
                        // call a helper which throws the error but "returns object"
                        sets.Add(
                            Ast.Convert(
                                Ast.Call(
                                    typeof(ScriptingRuntimeHelpers).GetMethod("ReadOnlyAssignError"),
                                    AstUtils.Constant(false),
                                    AstUtils.Constant(pi.Name)
                                    ),
                                pi.PropertyType
                                )
                            );
                    }
                }
            }

            sets.Add(
                tmp
                );

            Expression newCall = Ast.Block(
                sets.ToArray()
                );

            return(_builder.ToExpression(resolver, builders, args, newCall));
        }
コード例 #4
0
        internal Expression MakeExpression(ParameterBinder parameterBinder, IList <Expression> parameters)
        {
            bool[]       usageMarkers;
            Expression[] spilledArgs;
            Expression[] args = GetArgumentExpressions(parameterBinder, parameters, out usageMarkers, out spilledArgs);

            MethodBase mb = Method;
            MethodInfo mi = mb as MethodInfo;
            Expression ret, call;

            if (!mb.IsPublic || (mb.DeclaringType != null && !mb.DeclaringType.IsVisible))
            {
                if (mi != null)
                {
                    mi = CompilerHelpers.GetCallableMethod(mi, _binder._binder.PrivateBinding);
                    if (mi != null)
                    {
                        mb = mi;
                    }
                }
            }

            ConstructorInfo ci = mb as ConstructorInfo;

            Debug.Assert(mi != null || ci != null);
            if (mb.IsPublic && (mb.DeclaringType == null || mb.DeclaringType.IsVisible))
            {
                // public method
                if (mi != null)
                {
                    Expression instance = mi.IsStatic ? null : _instanceBuilder.ToExpression(parameterBinder, parameters, usageMarkers);
                    call = AstUtils.SimpleCallHelper(instance, mi, args);
                }
                else
                {
                    call = AstUtils.SimpleNewHelper(ci, args);
                }
            }
            else
            {
                // Private binding, invoke via reflection
                if (mi != null)
                {
                    Expression instance = mi.IsStatic ? Ast.Constant(null) : _instanceBuilder.ToExpression(parameterBinder, parameters, usageMarkers);
                    Debug.Assert(instance != null, "Can't skip instance expression");

                    call = Ast.Call(
                        typeof(BinderOps).GetMethod("InvokeMethod"),
                        Ast.Constant(mi),
                        AstUtils.Convert(instance, typeof(object)),
                        AstUtils.NewArrayHelper(typeof(object), args)
                        );
                }
                else
                {
                    call = Ast.Call(
                        typeof(BinderOps).GetMethod("InvokeConstructor"),
                        Ast.Constant(ci),
                        AstUtils.NewArrayHelper(typeof(object), args)
                        );
                }
            }

            if (spilledArgs != null)
            {
                call = Expression.Block(spilledArgs.AddLast(call));
            }

            ret = _returnBuilder.ToExpression(parameterBinder, _argBuilders, parameters, call);

            List <Expression> updates = null;

            for (int i = 0; i < _argBuilders.Count; i++)
            {
                Expression next = _argBuilders[i].UpdateFromReturn(parameterBinder, parameters);
                if (next != null)
                {
                    if (updates == null)
                    {
                        updates = new List <Expression>();
                    }
                    updates.Add(next);
                }
            }

            if (updates != null)
            {
                if (ret.Type != typeof(void))
                {
                    ParameterExpression temp = Ast.Variable(ret.Type, "$ret");
                    updates.Insert(0, Ast.Assign(temp, ret));
                    updates.Add(temp);
                    ret = Ast.Block(new [] { temp }, updates.ToArray());
                }
                else
                {
                    updates.Insert(0, ret);
                    ret = Ast.Convert(
                        Ast.Block(updates.ToArray()),
                        typeof(void)
                        );
                }
            }

            if (parameterBinder.Temps != null)
            {
                ret = Ast.Block(parameterBinder.Temps, ret);
            }

            return(ret);
        }