internal static CallSignature GetReversedSignature(CallSignature signature) { return new CallSignature(ArrayUtils.Append(signature.GetArgumentInfos(), new Argument(ArgumentType.Simple))); }
internal static CallSignature GetReversedSignature(CallSignature signature) { return(new CallSignature(ArrayUtils.Append(signature.GetArgumentInfos(), new Argument(ArgumentType.Simple)))); }
private DynamicMetaObject InvokeWorker(DynamicMetaObjectBinder /*!*/ callAction, DynamicMetaObject /*!*/[] args) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Method Invoke " + args.Length); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "Method"); CallSignature signature = BindingHelpers.GetCallSignature(callAction); DynamicMetaObject self = Restrict(typeof(Method)); BindingRestrictions restrictions = self.Restrictions; // restrict to non-null self (Method is immutable so this is an invariant test) restrictions = restrictions.Merge( BindingRestrictions.GetExpressionRestriction( Ast.NotEqual( GetSelfExpression(self), AstUtils.Constant(null) ) ) ); DynamicMetaObject[] newArgs = ArrayUtils.Insert(GetMetaFunction(self), GetMetaSelf(self), args); var newSig = new CallSignature(ArrayUtils.Insert(new Argument(ArgumentType.Simple), signature.GetArgumentInfos())); var call = new DynamicMetaObject( DynamicExpression.Dynamic( PythonContext.GetPythonContext(callAction).Invoke( newSig ).GetLightExceptionBinder(callAction.SupportsLightThrow()), typeof(object), ArrayUtils.Insert(PythonContext.GetCodeContext(callAction), DynamicUtils.GetExpressions(newArgs)) ), BindingRestrictions.Empty ); /* * call = func.Invoke( * new CallBinder( * PythonContext.GetBinderState(callAction), * newSig * ), * newArgs * );*/ if (call.HasValue) { return(new DynamicMetaObject( call.Expression, restrictions.Merge(call.Restrictions), call.Value )); } else { return(new DynamicMetaObject( call.Expression, restrictions.Merge(call.Restrictions) )); } }
private DynamicMetaObject InvokeWorker(DynamicMetaObjectBinder /*!*/ callAction, DynamicMetaObject /*!*/[] args) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "Method Invoke " + args.Length); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "Method"); CallSignature signature = BindingHelpers.GetCallSignature(callAction); DynamicMetaObject self = Restrict(typeof(Method)); BindingRestrictions restrictions = self.Restrictions; DynamicMetaObject func = GetMetaFunction(self); DynamicMetaObject call; if (Value.im_self == null) { // restrict to null self (Method is immutable so this is an invariant test) restrictions = restrictions.Merge( BindingRestrictions.GetExpressionRestriction( Ast.Equal( GetSelfExpression(self), AstUtils.Constant(null) ) ) ); if (args.Length == 0) { // this is an error, we pass null which will throw the normal error call = new DynamicMetaObject( Ast.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.MethodCheckSelf)), PythonContext.GetCodeContext(callAction), self.Expression, AstUtils.Constant(null) ), restrictions ); } else { // this may or may not be an error call = new DynamicMetaObject( Ast.Block( MakeCheckSelf(callAction, signature, args), DynamicExpression.Dynamic( PythonContext.GetPythonContext(callAction).Invoke( BindingHelpers.GetCallSignature(callAction) ).GetLightExceptionBinder(callAction.SupportsLightThrow()), typeof(object), ArrayUtils.Insert(PythonContext.GetCodeContext(callAction), DynamicUtils.GetExpressions(ArrayUtils.Insert(func, args))) ) ), BindingRestrictions.Empty ); /*call = func.Invoke(callAction, ArrayUtils.Insert(func, args)); * call = new MetaObject( * Ast.Comma( * Ast.Call( * typeof(PythonOps).GetMethod(nameof(PythonOps.MethodCheckSelf)), * self.Expression, * args[0].Expression * ), * call.Expression * ), * call.Restrictions * );*/ } } else { // restrict to non-null self (Method is immutable so this is an invariant test) restrictions = restrictions.Merge( BindingRestrictions.GetExpressionRestriction( Ast.NotEqual( GetSelfExpression(self), AstUtils.Constant(null) ) ) ); DynamicMetaObject im_self = GetMetaSelf(self); DynamicMetaObject[] newArgs = ArrayUtils.Insert(func, im_self, args); CallSignature newSig = new CallSignature(ArrayUtils.Insert(new Argument(ArgumentType.Simple), signature.GetArgumentInfos())); call = new DynamicMetaObject( DynamicExpression.Dynamic( PythonContext.GetPythonContext(callAction).Invoke( newSig ).GetLightExceptionBinder(callAction.SupportsLightThrow()), typeof(object), ArrayUtils.Insert(PythonContext.GetCodeContext(callAction), DynamicUtils.GetExpressions(newArgs)) ), BindingRestrictions.Empty ); /* * call = func.Invoke( * new CallBinder( * PythonContext.GetBinderState(callAction), * newSig * ), * newArgs * );*/ } if (call.HasValue) { return(new DynamicMetaObject( call.Expression, restrictions.Merge(call.Restrictions), call.Value )); } else { return(new DynamicMetaObject( call.Expression, restrictions.Merge(call.Restrictions) )); } }
/// <summary> /// Translates our CallSignature into a DLR Argument list and gives the simple MetaObject's which are extracted /// from the tuple or dictionary parameters being splatted. /// </summary> private void TranslateArguments(DynamicMetaObject target, DynamicMetaObject /*!*/[] /*!*/ args, out CallInfo /*!*/ callInfo, out List <Expression /*!*/> /*!*/ metaArgs, out Expression test, out BindingRestrictions restrictions) { Argument[] argInfo = _signature.GetArgumentInfos(); List <string> namedArgNames = new List <string>(); metaArgs = new List <Expression>(); metaArgs.Add(target.Expression); Expression splatArgTest = null; Expression splatKwArgTest = null; restrictions = BindingRestrictions.Empty; for (int i = 0; i < argInfo.Length; i++) { Argument ai = argInfo[i]; switch (ai.Kind) { case ArgumentType.Dictionary: PythonDictionary iac = (PythonDictionary)args[i].Value; List <string> argNames = new List <string>(); foreach (KeyValuePair <object, object> kvp in iac) { string key = (string)kvp.Key; namedArgNames.Add(key); argNames.Add(key); metaArgs.Add( Expression.Call( AstUtils.Convert(args[i].Expression, typeof(PythonDictionary)), typeof(PythonDictionary).GetMethod("get_Item", new[] { typeof(object) }), AstUtils.Constant(key) ) ); } restrictions = restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(args[i].Expression, args[i].GetLimitType())); splatKwArgTest = Expression.Call( typeof(PythonOps).GetMethod("CheckDictionaryMembers"), AstUtils.Convert(args[i].Expression, typeof(PythonDictionary)), AstUtils.Constant(argNames.ToArray()) ); break; case ArgumentType.List: IList <object> splattedArgs = (IList <object>)args[i].Value; splatArgTest = Expression.Equal( Expression.Property(AstUtils.Convert(args[i].Expression, args[i].GetLimitType()), typeof(ICollection <object>).GetProperty("Count")), AstUtils.Constant(splattedArgs.Count) ); for (int splattedArg = 0; splattedArg < splattedArgs.Count; splattedArg++) { metaArgs.Add( Expression.Call( AstUtils.Convert(args[i].Expression, typeof(IList <object>)), typeof(IList <object>).GetMethod("get_Item"), AstUtils.Constant(splattedArg) ) ); } restrictions = restrictions.Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(args[i].Expression, args[i].GetLimitType())); break; case ArgumentType.Named: namedArgNames.Add(ai.Name); metaArgs.Add(args[i].Expression); break; case ArgumentType.Simple: metaArgs.Add(args[i].Expression); break; default: throw new InvalidOperationException(); } } callInfo = new CallInfo(metaArgs.Count - 1, namedArgNames.ToArray()); test = splatArgTest; if (splatKwArgTest != null) { if (test != null) { test = Expression.AndAlso(test, splatKwArgTest); } else { test = splatKwArgTest; } } }