Ejemplo n.º 1
0
        internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
            if (_tmp == null) {
                _tmp = resolver.GetTemporary(_elementType, "outParam");
            }

            Debug.Assert(!hasBeenUsed[Index]);
            hasBeenUsed[Index] = true;
            Type boxType = typeof(StrongBox<>).MakeGenericType(_elementType);
            Expression arg = args.GetObject(Index).Expression;

            return Expression.Condition(
                Expression.TypeIs(arg, Type),
                Expression.Assign(
                    _tmp,
                    Expression.Field(
                        AstUtils.Convert(arg, boxType),
                        boxType.GetField("Value")
                    )
                ),
                Expression.Call(
                    typeof(RuntimeHelpers).GetMethod("IncorrectBoxType").MakeGenericMethod(_elementType),
                    AstUtils.Convert(arg, typeof(object))
                )
            );
        }
Ejemplo n.º 2
0
        internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
            if (_tmp == null) {
                _tmp = resolver.GetTemporary(_elementType, "outParam");
            }

            Debug.Assert(!hasBeenUsed[Index]);
            hasBeenUsed[Index] = true;
            Expression arg = args.GetObject(Index).Expression;

            return Expression.Condition(
                Expression.TypeIs(arg, Type),
                Expression.Assign(
                    _tmp,
                    Expression.Field(
                        AstUtils.Convert(arg, Type),
                        Type.GetField("Value")
                    )
                ),
                Expression.Throw(
                    Expression.Call(
                        new Func<Type, object, Exception>(RuntimeHelpers.MakeIncorrectBoxTypeError).Method,
                        AstUtils.Constant(_elementType),
                        AstUtils.Convert(arg, typeof(object))
                    ),
                    _elementType
                )
            );
        }
Ejemplo n.º 3
0
 internal override Expression UpdateFromReturn(OverloadResolver resolver, RestrictedArguments args) {
     return Expression.Assign(
         Expression.Field(
             Expression.Convert(args.GetObject(Index).Expression, Type),
             Type.GetField("Value")
         ),
         _tmp
     );
 }
Ejemplo n.º 4
0
 private void GetCallableMethod(RestrictedArguments args, ref MethodInfo method) {
     // If we have a non-visible method see if we can find a better method which
     // will call the same thing but is visible. If this fails we still bind anyway - it's
     // the callers responsibility to filter out non-visible methods.
     //
     // We use limit type of the meta instance so that we can access methods inherited to that type 
     // as accessible via an interface implemented by the type. The type might be internal and the methods 
     // might not be accessible otherwise.
     method = CompilerHelpers.TryGetCallableMethod(args.GetObject(_index).LimitType, method);
 }
Ejemplo n.º 5
0
 private List<Expression> GetParameters(RestrictedArguments args, bool[] hasBeenUsed) {
     List<Expression> res = new List<Expression>(_nameIndexes.Length);
     for (int i = 0; i < _nameIndexes.Length; i++) {
         int parameterIndex = _nameIndexes[i] + _argIndex;
         if (!hasBeenUsed[parameterIndex]) {
             res.Add(args.GetObject(parameterIndex).Expression);
             hasBeenUsed[parameterIndex] = true;
         }
     }
     return res;
 }
Ejemplo n.º 6
0
        internal protected virtual Expression ToExpression(ref MethodInfo method, OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
            if (_index == -1) {
                return AstUtils.Constant(null);
            }

            Debug.Assert(hasBeenUsed.Length == args.Length);
            Debug.Assert(_index < args.Length);
            Debug.Assert(!hasBeenUsed[_index]);
            hasBeenUsed[_index] = true;

            GetCallableMethod(args, ref method);
            return resolver.Convert(args.GetObject(_index), args.GetType(_index), null, method.DeclaringType);
        }
Ejemplo n.º 7
0
        internal protected virtual Func<object[], object> ToDelegate(ref MethodInfo method, OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
            if (_index == -1) {
                return (_) => null;
            }

            GetCallableMethod(args, ref method);

            Func<object[], object> conv = resolver.GetConvertor(_index + 1, args.GetObject(_index), null, method.DeclaringType);
            if (conv != null) {
                return conv;
            }

            return (Func<object[], object>)Delegate.CreateDelegate(
                typeof(Func<object[], object>),
                _index + 1,
                typeof(ArgBuilder).GetMethod("ArgumentRead"));
        }
Ejemplo n.º 8
0
 private static RestrictedArguments MakeRestrictedArg(RestrictedArguments args, int index)
 {
     return new RestrictedArguments(new[] { args.GetObject(index) }, new[] { args.GetType(index) }, false);
 }
Ejemplo n.º 9
0
 internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
     Debug.Assert(hasBeenUsed.Length == args.Length);
     Debug.Assert(_index < args.Length);
     Debug.Assert(!hasBeenUsed[Index]);
     
     hasBeenUsed[_index] = true;
     return resolver.Convert(args.GetObject(_index), args.GetType(_index), ParameterInfo, _parameterType);
 }
Ejemplo n.º 10
0
        protected internal override Func<object[], object> ToDelegate(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
            Func<object[], object> conv = resolver.GetConvertor(_index + 1, args.GetObject(_index), ParameterInfo, _parameterType);
            if (conv != null) {
                return conv;
            }

            return (Func<object[], object>)Delegate.CreateDelegate(
                typeof(Func<object[], object>), 
                _index + 1, 
                typeof(ArgBuilder).GetMethod("ArgumentRead"));
        }
        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;
                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(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
                                )
                            );
                        }                        
                        break;

                    case MemberTypes.Property:
                        PropertyInfo pi = (PropertyInfo)_membersSet[i];
                        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
                                )
                            );
                        }
                        break;
                }
            }

            sets.Add(
                tmp
            );

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

            return _builder.ToExpression(resolver, builders, args, newCall);
        }
Ejemplo n.º 12
0
        internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed)
        {
            var actualArgs     = resolver.GetActualArguments();
            int splatIndex     = actualArgs.SplatIndex;
            int collapsedCount = actualArgs.CollapsedCount;
            int firstSplatted  = actualArgs.FirstSplattedArg;

            var result        = new Expression[2 + _expandedCount + (collapsedCount > 0 ? 2 : 0)];
            var arrayVariable = resolver.GetTemporary(_elementType.MakeArrayType(), "a");
            int e             = 0;

            result[e++] = Ast.Assign(arrayVariable, Ast.NewArrayBounds(_elementType, Ast.Constant(_expandedCount + collapsedCount)));

            int itemIndex = 0;
            int i         = _start;

            while (true)
            {
                // inject loop copying collapsed items:
                if (i == splatIndex)
                {
                    var indexVariable = resolver.GetTemporary(typeof(int), "t");

                    // for (int t = 0; t <= {collapsedCount}; t++) {
                    //   a[{itemIndex} + t] = CONVERT<ElementType>(list.get_Item({splatIndex - firstSplatted} + t))
                    // }
                    result[e++] = Ast.Assign(indexVariable, AstUtils.Constant(0));
                    result[e++] = AstUtils.Loop(
                        Ast.LessThan(indexVariable, Ast.Constant(collapsedCount)),
                        // TODO: not implemented in the old interpreter
                        // Ast.PostIncrementAssign(indexVariable),
                        Ast.Assign(indexVariable, Ast.Add(indexVariable, AstUtils.Constant(1))),
                        Ast.Assign(
                            Ast.ArrayAccess(arrayVariable, Ast.Add(AstUtils.Constant(itemIndex), indexVariable)),
                            resolver.Convert(
                                new DynamicMetaObject(
                                    resolver.GetSplattedItemExpression(Ast.Add(AstUtils.Constant(splatIndex - firstSplatted), indexVariable)),
                                    BindingRestrictions.Empty
                                    ),
                                null,
                                ParameterInfo,
                                _elementType
                                )
                            ),
                        null
                        );

                    itemIndex += collapsedCount;
                }

                if (i >= _start + _expandedCount)
                {
                    break;
                }

                Debug.Assert(!hasBeenUsed[i]);
                hasBeenUsed[i] = true;

                result[e++] = Ast.Assign(
                    Ast.ArrayAccess(arrayVariable, AstUtils.Constant(itemIndex++)),
                    resolver.Convert(args.GetObject(i), args.GetType(i), ParameterInfo, _elementType)
                    );

                i++;
            }

            result[e++] = arrayVariable;

            Debug.Assert(e == result.Length);
            return(Ast.Block(result));
        }
Ejemplo n.º 13
0
        internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) {
            var actualArgs = resolver.GetActualArguments();
            int splatIndex = actualArgs.SplatIndex;
            int collapsedCount = actualArgs.CollapsedCount;
            int firstSplatted = actualArgs.FirstSplattedArg;

            var result = new Expression[2 + _expandedCount + (collapsedCount > 0 ? 2 : 0)];
            var arrayVariable = resolver.GetTemporary(_elementType.MakeArrayType(), "a");
            int e = 0;
            result[e++] = Ast.Assign(arrayVariable, Ast.NewArrayBounds(_elementType, Ast.Constant(_expandedCount + collapsedCount)));

            int itemIndex = 0;
            int i = _start;
            while (true) {
                // inject loop copying collapsed items:
                if (i == splatIndex) {
                    var indexVariable = resolver.GetTemporary(typeof(int), "t");

                    // for (int t = 0; t <= {collapsedCount}; t++) {
                    //   a[{itemIndex} + t] = CONVERT<ElementType>(list.get_Item({splatIndex - firstSplatted} + t))
                    // }
                    result[e++] = Ast.Assign(indexVariable, AstUtils.Constant(0));
                    result[e++] = AstUtils.Loop(
                        Ast.LessThan(indexVariable, Ast.Constant(collapsedCount)),
                        // TODO: not implemented in the old interpreter
                        // Ast.PostIncrementAssign(indexVariable),
                        Ast.Assign(indexVariable, Ast.Add(indexVariable, AstUtils.Constant(1))),
                        Ast.Assign(
                            Ast.ArrayAccess(arrayVariable, Ast.Add(AstUtils.Constant(itemIndex), indexVariable)),
                            resolver.Convert(
                                new DynamicMetaObject(
                                    resolver.GetSplattedItemExpression(Ast.Add(AstUtils.Constant(splatIndex - firstSplatted), indexVariable)), 
                                    BindingRestrictions.Empty
                                ),
                                null,
                                ParameterInfo, 
                                _elementType
                            )
                        ),
                        null
                    );

                    itemIndex += collapsedCount;
                }

                if (i >= _start + _expandedCount) {
                    break;
                }

                Debug.Assert(!hasBeenUsed[i]);
                hasBeenUsed[i] = true;                

                result[e++] = Ast.Assign(
                    Ast.ArrayAccess(arrayVariable, AstUtils.Constant(itemIndex++)),
                    resolver.Convert(args.GetObject(i), args.GetType(i), ParameterInfo, _elementType)
                );

                i++;
            }

            result[e++] = arrayVariable;

            Debug.Assert(e == result.Length);
            return Ast.Block(result);
        }
Ejemplo n.º 14
0
        public 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(
                Expression.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(
                            Expression.Assign(
                                Expression.Field(tmp, fi),
                                ConvertToHelper(resolver, value, fi.FieldType)
                                )
                            );
                    }
                    else
                    {
                        // call a helper which throws the error but "returns object"
                        sets.Add(
                            Expression.Convert(
                                Expression.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(
                            Expression.Assign(
                                Expression.Property(tmp, pi),
                                ConvertToHelper(resolver, value, pi.PropertyType)
                                )
                            );
                    }
                    else
                    {
                        // call a helper which throws the error but "returns object"
                        sets.Add(
                            Expression.Convert(
                                Expression.Call(
                                    typeof(ScriptingRuntimeHelpers).GetMethod("ReadOnlyAssignError"),
                                    AstUtils.Constant(false),
                                    AstUtils.Constant(pi.Name)
                                    ),
                                pi.PropertyType
                                )
                            );
                    }
                }
            }

            sets.Add(
                tmp
                );

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

            return(_builder.ToExpression(resolver, builders, args, newCall));
        }
Ejemplo n.º 15
0
 private static RestrictedArguments MakeRestrictedArg(RestrictedArguments args, int index)
 {
     return(new RestrictedArguments(new[] { args.GetObject(index) }, new[] { args.GetType(index) }, false));
 }