/// <summary> /// Attempts to bind to an operator Call method. /// </summary> private TargetInfo TryGetOperatorTargets(DynamicMetaObject self, DynamicMetaObject[] args, object target) { MethodBase[] targets; Type targetType = CompilerHelpers.GetType(target); MemberGroup callMembers = GetMember(MemberRequestKind.Invoke, targetType, "Call"); List <MethodBase> callTargets = new List <MethodBase>(); foreach (MemberTracker mi in callMembers) { if (mi.MemberType == TrackerTypes.Method) { MethodInfo method = ((MethodTracker)mi).Method; if (method.IsSpecialName) { callTargets.Add(method); } } } Expression instance = null; if (callTargets.Count > 0) { targets = callTargets.ToArray(); instance = Ast.Convert(self.Expression, CompilerHelpers.GetType(target)); return(new TargetInfo(null, ArrayUtils.Insert(self, args), targets)); } return(null); }
private MethodBase[] GetOperatorTargets(object target) { MethodBase[] targets = null; // see if the type defines a well known Call method Type targetType = CompilerHelpers.GetType(target); MemberGroup callMembers = Binder.GetMember(Action, targetType, "Call"); List <MethodBase> callTargets = new List <MethodBase>(); foreach (MemberTracker mi in callMembers) { if (mi.MemberType == TrackerTypes.Method) { MethodInfo method = ((MethodTracker)mi).Method; if (method.IsSpecialName) { callTargets.Add(method); } } } if (callTargets.Count > 0) { targets = callTargets.ToArray(); _instance = Ast.Convert(_rule.Parameters[0], CompilerHelpers.GetType(Callable)); } return(targets); }
private void MakeParamsDictionaryTest() { IDictionary dict = (IDictionary)_args[_args.Length - 1]; IDictionaryEnumerator dictEnum = dict.GetEnumerator(); // verify the dictionary has the same count and arguments. string[] names = new string[dict.Count]; int index = 0; while (dictEnum.MoveNext()) { string name = dictEnum.Entry.Key as string; if (name == null) { throw new ArgumentTypeException(String.Format("expected string for dictionary argument got {0}", dictEnum.Entry.Key)); } names[index++] = name; } _test = Ast.AndAlso( _test, Ast.AndAlso( Ast.TypeIs(_rule.Parameters[_rule.Parameters.Count - 1], typeof(IDictionary)), Ast.Call( typeof(ScriptingRuntimeHelpers).GetMethod("CheckDictionaryMembers"), Ast.Convert(_rule.Parameters[_rule.Parameters.Count - 1], typeof(IDictionary)), Ast.Constant(names) ) ) ); }
internal static DynamicMetaObject /*!*/ ConvertComArgument(DynamicMetaObject /*!*/ arg) { Expression expr = arg.Expression; BindingRestrictions restrictions; if (arg.Value != null) { Type type = arg.Value.GetType(); if (type == typeof(BigInteger)) { expr = Ast.Convert(AstUtils.Convert(arg.Expression, typeof(BigInteger)), typeof(double)); } else if (type == typeof(MutableString)) { // TODO: encoding? expr = Ast.Convert(AstUtils.Convert(arg.Expression, typeof(MutableString)), typeof(string)); } else if (type == typeof(RubySymbol)) { // TODO: encoding? expr = Ast.Convert(AstUtils.Convert(arg.Expression, typeof(RubySymbol)), typeof(string)); } restrictions = BindingRestrictions.GetTypeRestriction(arg.Expression, type); } else { restrictions = BindingRestrictions.GetExpressionRestriction(Ast.Equal(arg.Expression, AstUtils.Constant(null))); } return(arg.Clone(expr, restrictions)); }
/// <summary> /// Helper to extract the value from an Extensible of T /// </summary> private static DynamicMetaObject MakeExtensibleTarget(Type extensibleType, BindingRestrictions restrictions, DynamicMetaObject arg) { return(new DynamicMetaObject( Ast.Property(Ast.Convert(arg.Expression, extensibleType), extensibleType.GetInheritedProperties("Value").First()), restrictions )); }
/// <summary> /// Helper to extract the value from an Extensible of T /// </summary> private static MetaObject MakeExtensibleTarget(Type extensibleType, Restrictions restrictions, MetaObject arg) { return(new MetaObject( Ast.Property(Ast.Convert(arg.Expression, extensibleType), extensibleType.GetProperty("Value")), restrictions )); }
/// <summary> /// Creates a target which returns null for a reference type. /// </summary> private static MetaObject MakeNullTarget(Type toType, Restrictions restrictions) { return(new MetaObject( Ast.Convert(Ast.Constant(null), toType), restrictions )); }
public static UnaryExpression GetParamsList(StandardRule <T> rule) { return(Ast.Convert( rule.Parameters[rule.ParameterCount - 1], typeof(IList <object>) )); }
// TODO: This is a copy of CallSiteBinder.Stitch. private LambdaExpression /*!*/ Stitch <T>(Expression /*!*/ binding) where T : class { Expression updLabel = Expression.Label(CallSiteBinder.UpdateLabel); var site = Expression.Parameter(typeof(CallSite), "$site"); var @params = ArrayUtils.Insert(site, Parameters); var body = Expression.Block( binding, updLabel, Expression.Label( ReturnLabel, Expression.Invoke( Expression.Property( Ast.Convert(site, typeof(CallSite <T>)), typeof(CallSite <T>).GetProperty("Update") ), @params ) ) ); return(Expression.Lambda <T>( body, "CallSite.Target", true, // always compile the rules with tail call optimization @params )); }
public override Microsoft.Scripting.Ast.Expression Call(ActionBinder binder, params Expression[] arguments) { if (Method.IsPublic && Method.DeclaringType.IsVisible) { // TODO: Need to use MethodBinder in here to make this right. return(binder.MakeCallExpression(Method, arguments)); } //methodInfo.Invoke(obj, object[] params) if (Method.IsStatic) { return(Ast.Convert( Ast.Call( Ast.RuntimeConstant(Method), typeof(MethodInfo).GetMethod("Invoke", new Type[] { typeof(object), typeof(object[]) }), Ast.Null(), Ast.NewArrayHelper(typeof(object[]), arguments)), Method.ReturnType)); } if (arguments.Length == 0) { throw new InvalidOperationException("no instance for call"); } return(Ast.Convert( Ast.Call( Ast.RuntimeConstant(Method), typeof(MethodInfo).GetMethod("Invoke", new Type[] { typeof(object), typeof(object[]) }), arguments[0], Ast.NewArrayHelper(typeof(object[]), ArrayUtils.RemoveFirst(arguments))), Method.ReturnType)); }
private void MakeParamsDictionaryTest() { IDictionary dict = (IDictionary)_args[_args.Length - 1]; IDictionaryEnumerator dictEnum = dict.GetEnumerator(); // verify the dictionary has the same count and arguments. string[] names = new string[dict.Count]; int index = 0; while (dictEnum.MoveNext()) { names[index++] = (string)dictEnum.Entry.Key; } _test = Ast.AndAlso( _test, Ast.AndAlso( Ast.TypeIs(_rule.Parameters[_rule.Parameters.Length - 1], typeof(IDictionary)), Ast.Call( typeof(BinderOps).GetMethod("CheckDictionaryMembers"), Ast.Convert(_rule.Parameters[_rule.Parameters.Length - 1], typeof(IDictionary)), _rule.AddTemplatedConstant(typeof(string[]), names) ) ) ); }
private MethodBase[] GetOperatorTargets(object target) { MethodBase[] targets = null; // see if the type defines a well known Call method Type targetType = CompilerHelpers.GetType(target); // some of these define SpecialName, work around that until the interfaces go away entirely... if (!typeof(ICallableWithCodeContext).IsAssignableFrom(targetType) && !typeof(IFancyCallable).IsAssignableFrom(targetType)) { MemberGroup callMembers = Binder.GetMember(Action, targetType, "Call"); List <MethodBase> callTargets = new List <MethodBase>(); foreach (MemberTracker mi in callMembers) { if (mi.MemberType == TrackerTypes.Method) { MethodInfo method = ((MethodTracker)mi).Method; if (method.IsSpecialName) { callTargets.Add(method); } } } if (callTargets.Count > 0) { targets = callTargets.ToArray(); _instance = Ast.Convert(_rule.Parameters[0], CompilerHelpers.GetType(_args[0])); } } return(targets); }
internal override Expression ToExpression(MethodBinderContext context, Expression[] parameters) { // Ideally we'd pass in Ast.ReadField(parameters[Index], "Value") but due to // a bug in partial trust we can't access the generic field. // arg is boxType ? &_tmp : throw new ArgumentTypeException() // IncorrectBoxType throws the exception to avoid stack imbalance issues. return(Ast.Condition( Ast.TypeIs(parameters[Index], BoxType), Ast.Comma( Ast.Assign( _tmp, Ast.Call( typeof(BinderOps).GetMethod("GetBox").MakeGenericMethod(_elementType), Ast.ConvertHelper(parameters[Index], typeof(StrongBox <>).MakeGenericType(_elementType)) ) ), Ast.Read(_tmp) ), // Condition requires types of both expressions to be identical. // Putting the cast here is a temporary workaround until the // emit address and reference argument passing is finished. Ast.Convert( Ast.Call( typeof(BinderOps).GetMethod("IncorrectBoxType"), Ast.Constant(BoxType), Ast.ConvertHelper(parameters[Index], typeof(object)) ), _elementType ) )); }
private bool TryNumericComparison(OperatorInfo info) { MethodInfo[] targets = FilterNonMethods(_types[0], Binder.GetMember(Action, _types[0], "Compare")); if (targets.Length > 0) { MethodBinder mb = MethodBinder.MakeBinder(Binder, targets[0].Name, targets); BindingTarget target = mb.MakeBindingTarget(CallTypes.None, _types); if (target.Success) { Expression call = Ast.Convert(target.MakeExpression(_rule, _rule.Parameters), typeof(int)); switch (info.Operator) { case Operators.GreaterThan: call = Ast.GreaterThan(call, Ast.Constant(0)); break; case Operators.LessThan: call = Ast.LessThan(call, Ast.Constant(0)); break; case Operators.GreaterThanOrEqual: call = Ast.GreaterThanOrEqual(call, Ast.Constant(0)); break; case Operators.LessThanOrEqual: call = Ast.LessThanOrEqual(call, Ast.Constant(0)); break; case Operators.Equals: call = Ast.Equal(call, Ast.Constant(0)); break; case Operators.NotEquals: call = Ast.NotEqual(call, Ast.Constant(0)); break; case Operators.Compare: break; } _rule.Target = _rule.MakeReturn(Binder, call); return(true); } } return(false); }
internal override System.Linq.Expressions.Expression Call(Expression context, ActionBinder binder, params Expression[] arguments) { if (Method.IsPublic && Method.DeclaringType.IsVisible) { // TODO: Need to use MethodBinder in here to make this right. return(binder.MakeCallExpression(context, Method, arguments)); } //methodInfo.Invoke(obj, object[] params) if (Method.IsStatic) { return(Ast.Convert( Ast.Call( Ast.Constant(Method), typeof(MethodInfo).GetMethod("Invoke", new Type[] { typeof(object), typeof(object[]) }), Ast.Constant(null), AstUtils.NewArrayHelper(typeof(object), arguments) ), Method.ReturnType)); } if (arguments.Length == 0) { throw Error.NoInstanceForCall(); } return(Ast.Convert( Ast.Call( Ast.Constant(Method), typeof(MethodInfo).GetMethod("Invoke", new Type[] { typeof(object), typeof(object[]) }), arguments[0], AstUtils.NewArrayHelper(typeof(object), ArrayUtils.RemoveFirst(arguments)) ), Method.ReturnType)); }
protected override ActualArguments CreateActualArguments(IList <DynamicMetaObject> namedArgs, IList <string> argNames, int preSplatLimit, int postSplatLimit) { var res = new List <DynamicMetaObject>(); if (CallType == CallTypes.ImplicitInstance) { res.Add(_args[0]); } for (int i = 0; i < _signature.ArgumentCount; i++) { var arg = GetArgument(i); switch (_signature.GetArgumentKind(i)) { case ArgumentType.Simple: case ArgumentType.Instance: res.Add(arg); break; case ArgumentType.List: // TODO: lazy splat IList <object> list = arg.Value as IList <object>; if (list == null) { _invalidSplattee = arg; return(null); } for (int j = 0; j < list.Count; j++) { res.Add( DynamicMetaObject.Create( list[j], Ast.Call( Ast.Convert( arg.Expression, typeof(IList <object>) ), typeof(IList <object>).GetMethod("get_Item"), AstUtils.Constant(j) ) ) ); } break; case ArgumentType.Named: case ArgumentType.Dictionary: // already processed break; default: throw new NotImplementedException(); } } res.TrimExcess(); return(new ActualArguments(res, namedArgs, argNames, _callType == CallTypes.ImplicitInstance ? 1 : 0, 0, -1, -1)); }
// see Ruby Language.doc/Runtime/Control Flow Implementation/Break internal override MSA.Expression /*!*/ Transform(AstGenerator /*!*/ gen) { MSA.Expression transformedReturnValue = TransformReturnValue(gen); // eval: if (gen.CompilerOptions.IsEval) { return(Methods.EvalBreak.OpCall(gen.CurrentScopeVariable, AstUtils.Box(transformedReturnValue))); } // loop: if (gen.CurrentLoop != null) { return(Ast.Block( Ast.Assign( gen.CurrentLoop.ResultVariable, Ast.Convert(transformedReturnValue, gen.CurrentLoop.ResultVariable.Type) ), Ast.Break(gen.CurrentLoop.BreakLabel), AstUtils.Empty() )); } // block: if (gen.CurrentBlock != null) { return(gen.Return(Methods.BlockBreak.OpCall(gen.CurrentBlock.BfcVariable, AstUtils.Box(transformedReturnValue)))); } // primary frame: return(Methods.MethodBreak.OpCall(AstUtils.Box(transformedReturnValue))); }
internal override Expression ToExpression(MethodBinderContext context, Expression[] parameters) { object val = _defaultValue; if (val is Missing) { val = CompilerHelpers.GetMissingValue(_argumentType); } #if FULL if (_argumentType.IsByRef) { Variable tmp = context.GetTemporary(_argumentType.GetElementType(), "optRef"); return(Ast.Comma( Ast.Assign( tmp, Ast.Convert(Ast.Constant(val), tmp.Type) ), Ast.Read(tmp) )); } #endif return(context.ConvertExpression(Ast.Constant(val), _argumentType)); }
/// <summary> /// Creates a target which creates a new dynamic method which contains a single /// dynamic site that invokes the callable object. /// /// TODO: This should be specialized for each callable object /// </summary> protected static DynamicMetaObject /*!*/ MakeDelegateTarget(DynamicMetaObjectBinder /*!*/ action, Type /*!*/ toType, DynamicMetaObject /*!*/ arg) { Debug.Assert(arg != null); PythonContext state = PythonContext.GetPythonContext(action); CodeContext context; if (state != null) { context = state.SharedContext; } else { context = DefaultContext.Default; } return(new DynamicMetaObject( Ast.Convert( Ast.Call( typeof(PythonOps).GetMethod("GetDelegate"), AstUtils.Constant(context), arg.Expression, AstUtils.Constant(toType) ), toType ), arg.Restrictions )); }
/// <summary> /// Helper to produce a rule when no conversion is required (the strong type of the expression /// input matches the type we're converting to or has an implicit conversion at the IL level) /// </summary> private void MakeSimpleConversionTarget(Type toType, Type knownType) { if (toType.IsValueType && _rule.ReturnType == typeof(object) && _rule.Parameters[0].Type == typeof(object)) { // boxed value type is being converted back to object. We've done // the type check, there's no need to unbox & rebox the value. infact // it breaks calls on instance methods so we need to avoid it. _rule.Target = _rule.MakeReturn( Binder, _rule.Parameters[0] ); } else { Expression arg = _rule.Parameters[0]; if (arg.Type != knownType && knownType != typeof(Null)) { arg = Ast.Convert(arg, CompilerHelpers.GetVisibleType(knownType)); } _rule.Target = _rule.MakeReturn( Binder, AstUtils.Convert(arg, CompilerHelpers.GetVisibleType(toType)) ); } }
internal override Expression GetBoundValue(ActionBinder binder, Type type, Expression instance) { if (DeclaringType.IsGenericType && DeclaringType.GetGenericTypeDefinition() == typeof(StrongBox <>)) { // work around a CLR bug where we can't access generic fields from dynamic methods. return(Ast.Call( typeof(BinderOps).GetMethod("GetBox").MakeGenericMethod(DeclaringType.GetGenericArguments()), Ast.ConvertHelper(instance, DeclaringType) )); } if (IsPublic && DeclaringType.IsPublic) { return(Ast.ReadField( Ast.Convert(instance, Field.DeclaringType), Field )); } return(Ast.Call( Ast.ConvertHelper(Ast.RuntimeConstant(Field), typeof(FieldInfo)), typeof(FieldInfo).GetMethod("GetValue"), Ast.ConvertHelper(instance, typeof(object)) )); }
internal override void BuildCallNoFlow(MetaObjectBuilder /*!*/ metaBuilder, CallArguments /*!*/ args, string /*!*/ name) { // TODO: splat, rhs, ... if (args.Signature.ArgumentCount == 0) { if (args.Signature.HasBlock) { metaBuilder.Result = Methods.HookupEvent.OpCall( AstUtils.Constant(this), args.TargetExpression, Ast.Convert(args.GetBlockExpression(), typeof(Proc)) ); } else { metaBuilder.Result = Methods.CreateEvent.OpCall( AstUtils.Constant(this), args.TargetExpression, AstUtils.Constant(name) ); } } else { metaBuilder.SetError(Methods.MakeWrongNumberOfArgumentsError.OpCall(Ast.Constant(args.Signature.ArgumentCount), Ast.Constant(0))); } }
public override Ast ConvertExpression(Ast expr, Type toType, ConversionResultKind kind, OverloadResolverFactory resolverFactory) { Type exprType = expr.Type; Type visType = CompilerHelpers.GetVisibleType(toType); if (typeof(IFn).IsAssignableFrom(exprType) && typeof(Delegate).IsAssignableFrom(visType)) { return(Ast.Call(typeof(Converter).GetMethod("ConvertToDelegate"), Ast.Convert(expr, typeof(IFn)), Expression.Constant(visType))); } // Follow through on our promise to convert IEnumerable<Object> or IEnumerable to IEnumerable<T> for any T if (toType.IsGenericType && !toType.IsAssignableFrom(expr.Type)) { // The following is inspired by IronPython.Runtime.Binding.Python.ConversionBinder.FallbackConvert Type genTo = toType.GetGenericTypeDefinition(); if (genTo == typeof(IList <>)) { return(MakeToGenericConversion(expr, toType, typeof(IList <object>), typeof(ListGenericWrapper <>))); } else if (genTo == typeof(IDictionary <,>)) { return(MakeToGenericConversion(expr, toType, typeof(IDictionary <object, object>), typeof(DictionaryGenericWrapper <,>))); } else if (genTo == typeof(IEnumerable <>)) { return(MakeToGenericConversion(expr, toType, typeof(IEnumerable), typeof(IEnumerableOfTWrapper <>))); } } return(base.ConvertExpression(expr, toType, kind, resolverFactory)); }
internal override Expression UpdateFromReturn(MethodBinderContext context, Expression[] parameters) { return(Ast.Call( typeof(BinderOps).GetMethod("UpdateBox").MakeGenericMethod(_elementType), Ast.Convert(parameters[Index], BoxType), Ast.Read(_tmp) )); }
/// <summary> /// Helper to extract the value from an Extensible of T /// </summary> private void MakeExtensibleTarget(Type extensibleType) { _rule.Target = _rule.MakeReturn( Binder, Ast.Property(Ast.Convert(_rule.Parameters[0], extensibleType), extensibleType.GetProperty("Value")) ); }
public static Expression ByteVectorRef(Expression[] values) { if (values.Length == 2) { return(Ast.Convert(Ast.ArrayIndex(Ast.ConvertHelper(values[0], typeof(byte[])), Ast.ConvertHelper(values[1], typeof(int))), typeof(int))); } UnsafeSyntaxError("$bytevector-ref", "expected 2 arguments", values); return(null); }
private Expression GetParamater(int index) { Expression expr = _rule.Parameters[index]; if (_types[index].IsAssignableFrom(expr.Type)) { return(expr); } return(Ast.Convert(expr, _types[index])); }
private static Restrictions GetFallbackRestrictions(Type t, EventTracker et, MetaObject self) { if (t == typeof(EventTracker)) { // // Test Generated: // BinderOps.GetEventHandlerType(((EventTracker)args[0]).Event) == et.Event.EventHandlerType // return(Restrictions.GetExpressionRestriction( Ast.Equal( Ast.Call( typeof(BinderOps).GetMethod("GetEventHandlerType"), Ast.Property( Ast.Convert( self.Expression, typeof(EventTracker) ), typeof(EventTracker).GetProperty("Event") ) ), Ast.Constant(et.Event.EventHandlerType) ) )); } else if (t == typeof(BoundMemberTracker)) { // // Test Generated: // BinderOps.GetEventHandlerType(((EventTracker)((BoundMemberTracker)args[0]).BountTo).Event) == et.Event.EventHandlerType // return(Restrictions.GetExpressionRestriction( Ast.Equal( Ast.Call( typeof(BinderOps).GetMethod("GetEventHandlerType"), Ast.Property( Ast.Convert( Ast.Property( Ast.Convert( self.Expression, typeof(BoundMemberTracker) ), typeof(BoundMemberTracker).GetProperty("BoundTo") ), typeof(EventTracker) ), typeof(EventTracker).GetProperty("Event") ) ), Ast.Constant(et.Event.EventHandlerType) ) )); } return(Restrictions.Empty); }
/// <summary> /// Helper to produce a conversion rule by calling the helper method to do the convert /// </summary> private void MakeConversionTarget(MethodTracker method, Type fromType, bool isImplicit) { Expression ret = _rule.MakeReturn( Binder, Binder.MakeCallExpression(_rule.Context, method.Method, Ast.Convert(_rule.Parameters[0], fromType)) ); ret = WrapForThrowingTry(isImplicit, ret); _rule.Target = ret; }
private Expression /*!*/ MarshalArgument(MetaObjectBuilder /*!*/ metaBuilder, DynamicMetaObject /*!*/ arg, ArgType parameterType) { object value = arg.Value; if (value == null) { metaBuilder.AddRestriction(Ast.Equal(arg.Expression, AstUtils.Constant(null))); } else { metaBuilder.AddTypeRestriction(value.GetType(), arg.Expression); } switch (parameterType) { case ArgType.Buffer: if (value == null) { return(AstUtils.Constant(null, typeof(byte[]))); } if (value is int && (int)value == 0) { metaBuilder.AddRestriction(Ast.Equal(AstUtils.Convert(arg.Expression, typeof(int)), AstUtils.Constant(0))); return(AstUtils.Constant(null, typeof(byte[]))); } if (value.GetType() == typeof(MutableString)) { return(Methods.GetMutableStringBytes.OpCall( AstUtils.Convert(arg.Expression, typeof(MutableString)) )); } return(Methods.GetMutableStringBytes.OpCall( AstUtils.LightDynamic(ConvertToStrAction.Make(_context), typeof(MutableString), arg.Expression) )); case ArgType.Int32: if (value is int) { return(AstUtils.Convert(arg.Expression, typeof(int))); } return(Ast.Convert( Ast.Call( AstUtils.LightDynamic(ConvertToIntAction.Make(_context), typeof(IntegerValue), arg.Expression), Methods.IntegerValue_ToUInt32Unchecked ), typeof(int) )); } throw Assert.Unreachable; }