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 ) ); }
internal override Expression ToExpression(OverloadResolver resolver, IList<ArgBuilder> builders, RestrictedArguments args, Expression ret) { if (_returnArgs.Count == 1) { if (_returnArgs[0] == -1) { return ret; } return Ast.Block(ret, builders[_returnArgs[0]].ToReturnExpression(resolver)); } Expression[] retValues = new Expression[_returnArgs.Count]; int rIndex = 0; bool usesRet = false; foreach (int index in _returnArgs) { if (index == -1) { usesRet = true; retValues[rIndex++] = ret; } else { retValues[rIndex++] = builders[index].ToReturnExpression(resolver); } } Expression retArray = AstUtils.NewArrayHelper(typeof(object), retValues); if (!usesRet) { retArray = Ast.Block(ret, retArray); } return resolver.GetByRefArrayExpression(retArray); }
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)) ) ); }
private readonly int _actualArgs; // gets the actual number of arguments provided /// <summary> /// Creates a new BindingTarget when the method binding has succeeded. /// </summary> internal BindingTarget(string name, int actualArgumentCount, MethodCandidate candidate, NarrowingLevel level, RestrictedArguments restrictedArgs) { _name = name; _candidate = candidate; _restrictedArgs = restrictedArgs; _level = level; _actualArgs = actualArgumentCount; }
public 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.GetDeclaredField("Value") ) ), Expression.Throw( Expression.Call( new Func <Type, object, Exception>(RuntimeHelpers.MakeIncorrectBoxTypeError).GetMethodInfo(), AstUtils.Constant(_elementType), AstUtils.Convert(arg, typeof(object)) ), _elementType ) )); }
internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { if (_tmp == null) { _tmp = resolver.GetTemporary(Type, "outParam"); } return Ast.Block(Ast.Assign(_tmp, base.ToExpression(resolver, args, hasBeenUsed)), _tmp); }
private readonly int[] _expectedArgs; // gets the acceptable number of parameters which can be passed to the method. /// <summary> /// Creates a new BindingTarget when the method binding has succeeded. /// </summary> internal BindingTarget(string name, int actualArgumentCount, MethodCandidate candidate, NarrowingLevel level, RestrictedArguments restrictedArgs) { Name = name; MethodCandidate = candidate; RestrictedArguments = restrictedArgs; NarrowingLevel = level; ActualArgumentCount = actualArgumentCount; }
internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { Debug.Assert(BuilderExpectsSingleParameter(_builder)); int index = GetKeywordIndex(args.Length); Debug.Assert(!hasBeenUsed[index]); hasBeenUsed[index] = true; return _builder.ToExpression(resolver, MakeRestrictedArg(args, index), new bool[1]); }
internal override Expression UpdateFromReturn(OverloadResolver resolver, RestrictedArguments args) { return Expression.Assign( Expression.Field( Expression.Convert(args.GetObject(Index).Expression, Type), Type.GetField("Value") ), _tmp ); }
internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { Expression res = Ast.Call( typeof(BinderOps).GetMethod("MakeSymbolDictionary"), Ast.NewArrayInit(typeof(string), ConstantNames()), AstUtils.NewArrayHelper(typeof(object), GetParameters(args, hasBeenUsed)) ); return res; }
public override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { if (_isRef) { return(_tmp ?? (_tmp = resolver.GetTemporary(_parameterType, "outParam"))); } return(GetDefaultValue()); }
public 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)); }
public override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { if (_tmp == null) { _tmp = resolver.GetTemporary(Type, "outParam"); } return(Expression.Block(Expression.Assign(_tmp, base.ToExpression(resolver, args, hasBeenUsed)), _tmp)); }
internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { Type dictType = ParameterInfo.ParameterType; return Ast.Call( GetCreationDelegate(dictType).Method, Ast.NewArrayInit(typeof(string), ConstantNames()), AstUtils.NewArrayHelper(typeof(object), GetParameters(args, hasBeenUsed)) ); }
internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { if (_isRef) { if (_tmp == null) { _tmp = resolver.GetTemporary(_parameterType, "outParam"); } return _tmp; } return GetDefaultValue(); }
internal override Expression UpdateFromReturn(OverloadResolver resolver, RestrictedArguments args) { return(Expression.Assign( Expression.Field( Expression.Convert(args.GetObject(Index).Expression, Type), Type.GetField("Value") ), _tmp )); }
public override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { Type dictType = ParameterInfo.ParameterType; return(Expression.Call( GetCreationDelegate(dictType).GetMethodInfo(), Expression.NewArrayInit(typeof(string), ConstantNames()), AstUtils.NewArrayHelper(typeof(object), GetParameters(args, hasBeenUsed)) )); }
public override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { Debug.Assert(BuilderExpectsSingleParameter(_builder)); int index = GetKeywordIndex(args.Length); Debug.Assert(!hasBeenUsed[index]); hasBeenUsed[index] = true; return(_builder.ToExpression(resolver, MakeRestrictedArg(args, index), new bool[1])); }
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); }
private Expression[] GetArgumentExpressions(RestrictedArguments restrictedArgs, out bool[] usageMarkers, out Expression[] spilledArgs) { int minPriority = Int32.MaxValue; int maxPriority = Int32.MinValue; foreach (ArgBuilder ab in _argBuilders) { minPriority = System.Math.Min(minPriority, ab.Priority); maxPriority = System.Math.Max(maxPriority, ab.Priority); } var args = new Expression[_argBuilders.Count]; Expression[] actualArgs = null; usageMarkers = new bool[restrictedArgs.Length]; for (int priority = minPriority; priority <= maxPriority; priority++) { for (int i = 0; i < _argBuilders.Count; i++) { if (_argBuilders[i].Priority == priority) { args[i] = _argBuilders[i].ToExpression(_resolver, restrictedArgs, usageMarkers); // see if this has a temp that needs to be passed as the actual argument Expression byref = _argBuilders[i].ByRefArgument; if (byref != null) { if (actualArgs == null) { actualArgs = new Expression[_argBuilders.Count]; } actualArgs[i] = byref; } } } } if (actualArgs != null) { for (int i = 0; i < args.Length; i++) { if (args[i] != null && actualArgs[i] == null) { actualArgs[i] = _resolver.GetTemporary(args[i].Type, null); args[i] = Expression.Assign(actualArgs[i], args[i]); } } spilledArgs = RemoveNulls(args); return(RemoveNulls(actualArgs)); } spilledArgs = null; return(RemoveNulls(args)); }
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; }
internal protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { object value = ParameterInfo.DefaultValue; if (value is Missing) { value = CompilerHelpers.GetMissingValue(ParameterInfo.ParameterType); } if (ParameterInfo.ParameterType.IsByRef) { return AstUtils.Constant(value, ParameterInfo.ParameterType.GetElementType()); } var metaValue = new DynamicMetaObject(AstUtils.Constant(value), BindingRestrictions.Empty, value); return resolver.Convert(metaValue, CompilerHelpers.GetType(value), ParameterInfo, ParameterInfo.ParameterType); }
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); }
internal OptimizingCallDelegate MakeDelegate(RestrictedArguments restrictedArgs) { if (restrictedArgs.HasUntypedRestrictions) { return(null); } MethodInfo mi = Overload.ReflectionInfo as MethodInfo; if (mi == null) { return(null); } Type declType = mi.GetBaseDefinition().DeclaringType; if (IsRestrictedType(declType)) { // members of reflection are off limits via reflection in partial trust return(null); } if (_returnBuilder.CountOutParams > 0) { return(null); } Func <object[], object>[] builders = new Func <object[], object> [_argBuilders.Count]; bool[] hasBeenUsed = new bool[restrictedArgs.Length]; for (int i = 0; i < _argBuilders.Count; i++) { var builder = _argBuilders[i].ToDelegate(_resolver, restrictedArgs, hasBeenUsed); if (builder == null) { return(null); } builders[i] = builder; } if (_instanceBuilder.HasValue) { var instance = _instanceBuilder.ToDelegate(ref mi, _resolver, restrictedArgs, hasBeenUsed); return(new Caller(mi, builders, instance).CallWithInstance); } else { return(new Caller(mi, builders, null).Call); } }
protected internal override Func<object[], object> ToDelegate(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { if (ParameterInfo.ParameterType.IsByRef) { return null; } else if (ParameterInfo.DefaultValue is Missing && CompilerHelpers.GetMissingValue(ParameterInfo.ParameterType) is Missing) { // reflection throws when we do this return null; } object val = ParameterInfo.DefaultValue; if (val is Missing) { val = CompilerHelpers.GetMissingValue(ParameterInfo.ParameterType); } Debug.Assert(val != Missing.Value); return (_) => val; }
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")); }
public override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { object value = ParameterInfo.GetDefaultValue(); if (value is Missing) { value = CompilerHelpers.GetMissingValue(ParameterInfo.ParameterType); } if (ParameterInfo.ParameterType.IsByRef) { return(AstUtils.Constant(value, ParameterInfo.ParameterType.GetElementType())); } var metaValue = new DynamicMetaObject(AstUtils.Constant(value), BindingRestrictions.Empty, value); return(resolver.Convert(metaValue, CompilerHelpers.GetType(value), ParameterInfo, ParameterInfo.ParameterType)); }
internal virtual Expression ToExpression(OverloadResolver resolver, IList <ArgBuilder> builders, RestrictedArguments args, Expression ret) { return(ret); }
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); }
private static RestrictedArguments MakeRestrictedArg(RestrictedArguments args, int index) { return(new RestrictedArguments(new[] { args.GetObject(index) }, new[] { args.GetType(index) }, false)); }
protected override Func<object[], object> ToDelegate(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { object value = Activator.CreateInstance(ParameterInfo.ParameterType); return (_) => value; }
internal override Expression UpdateFromReturn(OverloadResolver resolver, RestrictedArguments args) { int index = GetKeywordIndex(args.Length); return(_builder.UpdateFromReturn(resolver, MakeRestrictedArg(args, index))); }
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)); }
protected internal override Func<object[], object> ToDelegate(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { return null; }
protected internal override Func <object[], object> ToDelegate(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { if (ParameterInfo.ParameterType.IsByRef) { return(null); } else if (ParameterInfo.DefaultValue is Missing && CompilerHelpers.GetMissingValue(ParameterInfo.ParameterType) is Missing) { // reflection throws when we do this return(null); } object val = ParameterInfo.DefaultValue; if (val is Missing) { val = CompilerHelpers.GetMissingValue(ParameterInfo.ParameterType); } Debug.Assert(val != Missing.Value); return((_) => val); }
protected internal override Func <object[], object> ToDelegate(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { return(null); }
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"))); }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1045:DoNotPassTypesByReference")] // TODO 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)); }
private Expression[] GetArgumentExpressions(RestrictedArguments restrictedArgs, out bool[] usageMarkers, out Expression[] spilledArgs) { int minPriority = Int32.MaxValue; int maxPriority = Int32.MinValue; foreach (ArgBuilder ab in _argBuilders) { minPriority = System.Math.Min(minPriority, ab.Priority); maxPriority = System.Math.Max(maxPriority, ab.Priority); } var args = new Expression[_argBuilders.Count]; Expression[] actualArgs = null; usageMarkers = new bool[restrictedArgs.Length]; for (int priority = minPriority; priority <= maxPriority; priority++) { for (int i = 0; i < _argBuilders.Count; i++) { if (_argBuilders[i].Priority == priority) { args[i] = _argBuilders[i].ToExpression(_resolver, restrictedArgs, usageMarkers); // see if this has a temp that needs to be passed as the actual argument Expression byref = _argBuilders[i].ByRefArgument; if (byref != null) { if (actualArgs == null) { actualArgs = new Expression[_argBuilders.Count]; } actualArgs[i] = byref; } } } } if (actualArgs != null) { for (int i = 0; i < args.Length; i++) { if (args[i] != null && actualArgs[i] == null) { actualArgs[i] = _resolver.GetTemporary(args[i].Type, null); args[i] = Expression.Assign(actualArgs[i], args[i]); } } spilledArgs = RemoveNulls(args); return RemoveNulls(actualArgs); } spilledArgs = null; return RemoveNulls(args); }
/// <summary> /// Provides the Expression which provides the value to be passed to the argument. /// If <c>null</c> is returned the argument is skipped (not passed to the callee). /// </summary> public abstract Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed);
internal Expression MakeExpression(RestrictedArguments restrictedArgs) { Expression[] callArgs = GetArgumentExpressions(restrictedArgs, out bool[] usageMarkers, out Expression[] spilledArgs);
internal override Expression UpdateFromReturn(OverloadResolver resolver, RestrictedArguments args) { int index = GetKeywordIndex(args.Length); return _builder.UpdateFromReturn(resolver, MakeRestrictedArg(args, index)); }
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); }
protected internal override Func<object[], object> ToDelegate(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { string[] names = _names; int[] indexes = GetParameters(hasBeenUsed); Type dictType = ParameterInfo.ParameterType; Func<string[], object[], object> func = GetCreationDelegate(dictType); return (actualArgs) => { object[] values = new object[indexes.Length]; for (int i = 0; i < indexes.Length; i++) { values[i] = actualArgs[indexes[i] + 1]; } return func(names, values); }; }
/// <summary> /// Provides an Expression which will update the provided value after a call to the method. May /// return null if no update is required. /// </summary> internal virtual Expression UpdateFromReturn(OverloadResolver resolver, RestrictedArguments args) { return(null); }
protected override Expression/*!*/ ToExpression(ref MethodInfo/*!*/ method, OverloadResolver/*!*/ resolver, RestrictedArguments/*!*/ args, bool[]/*!*/ hasBeenUsed) { return ((RubyOverloadResolver)resolver)._args.TargetExpression; }
protected override Func<object[], object> ToDelegate(ref MethodInfo/*!*/ method, OverloadResolver/*!*/ resolver, RestrictedArguments/*!*/ args, bool[]/*!*/ hasBeenUsed) { return null; }
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")); }
protected override Expression ToExpression(OverloadResolver/*!*/ resolver, RestrictedArguments/*!*/ args, bool[]/*!*/ hasBeenUsed) { Debug.Assert(Index < args.Length); Debug.Assert(Index < hasBeenUsed.Length); hasBeenUsed[Index] = true; return null; }
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)); }
protected override Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { return AstUtils.Constant(Activator.CreateInstance(ParameterInfo.ParameterType)); }
protected internal override Func <object[], object> ToDelegate(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed) { if (resolver.GetActualArguments().CollapsedCount > 0) { return(null); } var indexes = new List <Func <object[], object> >(_expandedCount); for (int i = _start; i < _start + _expandedCount; i++) { if (!hasBeenUsed[i]) { indexes.Add(resolver.GetConvertor(i + 1, args.GetObject(i), ParameterInfo, _elementType)); hasBeenUsed[i] = true; } } if (_elementType == typeof(object)) { return(new ParamArrayDelegate <object>(indexes.ToArray(), _start).MakeParamsArray); } Type genType = typeof(ParamArrayDelegate <>).MakeGenericType(_elementType); return((Func <object[], object>)Delegate.CreateDelegate( typeof(Func <object[], object>), Activator.CreateInstance(genType, indexes.ToArray(), _start), genType.GetMethod("MakeParamsArray"))); }
internal override Expression ToExpression(OverloadResolver resolver, IList <ArgBuilder> builders, RestrictedArguments args, Expression ret) { if (_returnArgs.Count == 1) { if (_returnArgs[0] == -1) { return(ret); } return(Ast.Block(ret, builders[_returnArgs[0]].ToReturnExpression(resolver))); } Expression[] retValues = new Expression[_returnArgs.Count]; int rIndex = 0; bool usesRet = false; foreach (int index in _returnArgs) { if (index == -1) { usesRet = true; retValues[rIndex++] = ret; } else { retValues[rIndex++] = builders[index].ToReturnExpression(resolver); } } Expression retArray = AstUtils.NewArrayHelper(typeof(object), retValues); if (!usesRet) { retArray = Ast.Block(ret, retArray); } return(resolver.GetByRefArrayExpression(retArray)); }
protected override Expression ToExpression(OverloadResolver/*!*/ resolver, RestrictedArguments/*!*/ args, bool[]/*!*/ hasBeenUsed) { return AstUtils.Constant(Activator.CreateInstance(ParameterInfo.ParameterType, ((RubyOverloadResolver)resolver).Context)); }
protected override Expression ToExpression(OverloadResolver/*!*/ resolver, RestrictedArguments/*!*/ args, bool[]/*!*/ hasBeenUsed) { return ((RubyOverloadResolver)resolver).ScopeExpression; }
private static RestrictedArguments MakeRestrictedArg(RestrictedArguments args, int index) { return new RestrictedArguments(new[] { args.GetObject(index) }, new[] { args.GetType(index) }, false); }
/// <summary> /// Provides the Expression which provides the value to be passed to the argument. /// If <c>null</c> is returned the argument is skipped (not passed to the callee). /// </summary> internal protected abstract Expression ToExpression(OverloadResolver resolver, RestrictedArguments args, bool[] hasBeenUsed);