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)) ) ); }
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 UpdateFromReturn(OverloadResolver resolver, RestrictedArguments args) { return Expression.Assign( Expression.Field( Expression.Convert(args.GetObject(Index).Expression, Type), Type.GetField("Value") ), _tmp ); }
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 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 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 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")); }
private static RestrictedArguments MakeRestrictedArg(RestrictedArguments args, int index) { return new RestrictedArguments(new[] { args.GetObject(index) }, new[] { args.GetType(index) }, false); }
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) { 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); }
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)); }
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); }
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)); }
private static RestrictedArguments MakeRestrictedArg(RestrictedArguments args, int index) { return(new RestrictedArguments(new[] { args.GetObject(index) }, new[] { args.GetType(index) }, false)); }