static private GetCallSignature ( |
||
action | ||
Résultat | CallSignature |
/// <summary> /// Checks if we have a default new and init - in this case if we have any /// arguments we don't allow the call. /// </summary> private bool TooManyArgsForDefaultNew(DynamicMetaObjectBinder /*!*/ action, DynamicMetaObject /*!*/[] /*!*/ args) { if (args.Length > 0 && HasDefaultNewAndInit(action)) { Argument[] infos = BindingHelpers.GetCallSignature(action).GetArgumentInfos(); for (int i = 0; i < infos.Length; i++) { Argument curArg = infos[i]; switch (curArg.Kind) { case ArgumentType.List: // Deferral? if (((IList <object>)args[i].Value).Count > 0) { return(true); } break; case ArgumentType.Dictionary: // Deferral? if (PythonOps.Length(args[i].Value) > 0) { return(true); } break; default: return(true); } } } return(false); }
private DynamicMetaObject /*!*/ MakeCallRule(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject[] args) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass Invoke w/ " + args.Length + " args"); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass Invoke"); CallSignature signature = BindingHelpers.GetCallSignature(call); // TODO: If we know __init__ wasn't present we could construct the OldInstance directly. Expression[] exprArgs = new Expression[args.Length]; for (int i = 0; i < args.Length; i++) { exprArgs[i] = args[i].Expression; } ParameterExpression init = Ast.Variable(typeof(object), "init"); ParameterExpression instTmp = Ast.Variable(typeof(object), "inst"); DynamicMetaObject self = Restrict(typeof(OldClass)); return(new DynamicMetaObject( Ast.Block( new ParameterExpression[] { init, instTmp }, Ast.Assign( instTmp, Ast.New( typeof(OldInstance).GetConstructor(new Type[] { typeof(CodeContext), typeof(OldClass) }), codeContext, self.Expression ) ), Ast.Condition( Expression.Not( Expression.TypeIs( Expression.Assign( init, Ast.Call( typeof(PythonOps).GetMethod("OldClassTryLookupInit"), self.Expression, instTmp ) ), typeof(OperationFailed) ) ), Ast.Dynamic( PythonContext.GetPythonContext(call).Invoke( signature ), typeof(object), ArrayUtils.Insert <Expression>(codeContext, init, exprArgs) ), NoInitCheckNoArgs(signature, self, args) ), instTmp ), self.Restrictions.Merge(BindingRestrictions.Combine(args)) )); }
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 /*!*/ invoke, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] args) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass Invoke"); DynamicMetaObject self = Restrict(typeof(OldInstance)); Expression[] exprArgs = new Expression[args.Length + 1]; for (int i = 0; i < args.Length; i++) { exprArgs[i + 1] = args[i].Expression; } ParameterExpression tmp = Ast.Variable(typeof(object), "callFunc"); exprArgs[0] = tmp; return(new DynamicMetaObject( // we could get better throughput w/ a more specific rule against our current custom old class but // this favors less code generation. Ast.Block( new ParameterExpression[] { tmp }, Ast.Condition( Ast.Call( typeof(PythonOps).GetMethod("OldInstanceTryGetBoundCustomMember"), codeContext, self.Expression, AstUtils.Constant("__call__"), tmp ), Ast.Block( Utils.Try( Ast.Call(typeof(PythonOps).GetMethod("FunctionPushFrameCodeContext"), codeContext), Ast.Assign( tmp, Ast.Dynamic( PythonContext.GetPythonContext(invoke).Invoke( BindingHelpers.GetCallSignature(invoke) ), typeof(object), ArrayUtils.Insert(codeContext, exprArgs) ) ) ).Finally( Ast.Call(typeof(PythonOps).GetMethod("FunctionPopFrame")) ), tmp ), Utils.Convert( BindingHelpers.InvokeFallback(invoke, codeContext, this, args).Expression, typeof(object) ) ) ), self.Restrictions.Merge(BindingRestrictions.Combine(args)) )); }
private DynamicMetaObject /*!*/ InvokeWorker(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] args) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "BuiltinMethodDesc Invoke " + Value.DeclaringType + "." + Value.__name__ + " w/ " + args.Length + " args"); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "BuiltinMethodDesc Invoke"); CallSignature signature = BindingHelpers.GetCallSignature(call); BindingRestrictions selfRestrict = BindingRestrictions.GetInstanceRestriction(Expression, Value).Merge(Restrictions); selfRestrict = selfRestrict.Merge( BindingRestrictions.GetExpressionRestriction( MakeFunctionTest( Ast.Call( typeof(PythonOps).GetMethod("GetBuiltinMethodDescriptorTemplate"), Ast.Convert(Expression, typeof(BuiltinMethodDescriptor)) ) ) ) ); return(Value.Template.MakeBuiltinFunctionCall( call, codeContext, this, args, false, // no self selfRestrict, (newArgs) => { BindingTarget target; PythonContext state = PythonContext.GetPythonContext(call); DynamicMetaObject res = state.Binder.CallMethod( new PythonOverloadResolver( state.Binder, newArgs, signature, codeContext ), Value.Template.Targets, selfRestrict, Value.Template.Name, NarrowingLevel.None, Value.Template.IsBinaryOperator ? PythonNarrowing.BinaryOperator : NarrowingLevel.All, out target ); return BindingHelpers.CheckLightThrow(call, res, target); })); }
/// <summary> /// Creating a standard .NET type is easy - we just call it's constructor with the provided /// arguments. /// </summary> private DynamicMetaObject /*!*/ MakeStandardDotNetTypeCall(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] /*!*/ args) { CallSignature signature = BindingHelpers.GetCallSignature(call); PythonContext state = PythonContext.GetPythonContext(call); MethodBase[] ctors = CompilerHelpers.GetConstructors(Value.UnderlyingSystemType, state.Binder.PrivateBinding); if (ctors.Length > 0) { return(state.Binder.CallMethod( new PythonOverloadResolver( state.Binder, args, signature, codeContext ), ctors, Restrictions.Merge(BindingRestrictions.GetInstanceRestriction(Expression, Value)) )); } else { string msg; if (Value.UnderlyingSystemType.IsAbstract) { msg = String.Format("Cannot create instances of {0} because it is abstract", Value.Name); } else { msg = String.Format("Cannot create instances of {0} because it has no public constructors", Value.Name); } return(new DynamicMetaObject( call.Throw( Ast.New( typeof(TypeErrorException).GetConstructor(new Type[] { typeof(string) }), AstUtils.Constant(msg) ) ), Restrictions.Merge(BindingRestrictions.GetInstanceRestriction(Expression, Value)) )); } }
private DynamicMetaObject /*!*/ MakeSelflessCall(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] /*!*/ args) { // just check if it's the same built-in function. Because built-in functions are // immutable the identity check will suffice. Because built-in functions are uncollectible // anyway we don't use the typical InstanceRestriction. BindingRestrictions selfRestrict = BindingRestrictions.GetExpressionRestriction(Ast.Equal(Expression, AstUtils.Constant(Value))).Merge(Restrictions); return(Value.MakeBuiltinFunctionCall( call, codeContext, this, args, false, // no self selfRestrict, (newArgs) => { BindingTarget target; var binder = PythonContext.GetPythonContext(call).Binder; DynamicMetaObject res = binder.CallMethod( new PythonOverloadResolver( binder, newArgs, BindingHelpers.GetCallSignature(call), codeContext ), Value.Targets, selfRestrict, Value.Name, PythonNarrowing.None, Value.IsBinaryOperator ? PythonNarrowing.BinaryOperator : NarrowingLevel.All, out target ); return BindingHelpers.CheckLightThrow(call, res, target); } )); }
/// <summary> /// Creating a Python type involves calling __new__ and __init__. We resolve them /// and generate calls to either the builtin funcions directly or embed sites which /// call the slots at runtime. /// </summary> private DynamicMetaObject /*!*/ MakePythonTypeCall(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] /*!*/ args) { ValidationInfo valInfo = MakeVersionCheck(); DynamicMetaObject self = new RestrictedMetaObject( AstUtils.Convert(Expression, LimitType), BindingRestrictionsHelpers.GetRuntimeTypeRestriction(Expression, LimitType), Value ); CallSignature sig = BindingHelpers.GetCallSignature(call); ArgumentValues ai = new ArgumentValues(sig, self, args); NewAdapter newAdapter; InitAdapter initAdapter; if (TooManyArgsForDefaultNew(call, args)) { return(MakeIncorrectArgumentsForCallError(call, ai, valInfo)); } else if (Value.UnderlyingSystemType.IsGenericTypeDefinition) { return(MakeGenericTypeDefinitionError(call, ai, valInfo)); } else if (Value.HasAbstractMethods(PythonContext.GetPythonContext(call).SharedContext)) { return(MakeAbstractInstantiationError(call, ai, valInfo)); } DynamicMetaObject translated = BuiltinFunction.TranslateArguments(call, codeContext, self, args, false, Value.Name); if (translated != null) { return(translated); } GetAdapters(ai, call, codeContext, out newAdapter, out initAdapter); PythonContext state = PythonContext.GetPythonContext(call); // get the expression for calling __new__ DynamicMetaObject createExpr = newAdapter.GetExpression(state.Binder); if (createExpr.Expression.Type == typeof(void)) { return(BindingHelpers.AddDynamicTestAndDefer( call, createExpr, args, valInfo )); } Expression res; BindingRestrictions additionalRestrictions = BindingRestrictions.Empty; if (!Value.IsSystemType && (!(newAdapter is DefaultNewAdapter) || HasFinalizer(call))) { // we need to dynamically check the return value to see if it's a subtype of // the type that we are calling. If it is then we need to call __init__/__del__ // for the actual returned type. res = Expression.Dynamic( Value.GetLateBoundInitBinder(sig), typeof(object), ArrayUtils.Insert( codeContext, Expression.Convert(createExpr.Expression, typeof(object)), DynamicUtils.GetExpressions(args) ) ); additionalRestrictions = createExpr.Restrictions; } else { // just call the __init__ method, built-in types currently have // no wacky return values which don't return the derived type. // then get the statement for calling __init__ ParameterExpression allocatedInst = Ast.Variable(createExpr.GetLimitType(), "newInst"); Expression tmpRead = allocatedInst; DynamicMetaObject initCall = initAdapter.MakeInitCall( state.Binder, new RestrictedMetaObject( AstUtils.Convert(allocatedInst, Value.UnderlyingSystemType), createExpr.Restrictions ) ); List <Expression> body = new List <Expression>(); Debug.Assert(!HasFinalizer(call)); // add the call to init if we need to if (initCall.Expression != tmpRead) { // init can fail but if __new__ returns a different type // no exception is raised. DynamicMetaObject initStmt = initCall; if (body.Count == 0) { body.Add( Ast.Assign(allocatedInst, createExpr.Expression) ); } if (!Value.UnderlyingSystemType.IsAssignableFrom(createExpr.Expression.Type)) { // return type of object, we need to check the return type before calling __init__. body.Add( AstUtils.IfThen( Ast.TypeIs(allocatedInst, Value.UnderlyingSystemType), initStmt.Expression ) ); } else { // just call the __init__ method, no type check necessary (TODO: need null check?) body.Add(initStmt.Expression); } } // and build the target from everything we have if (body.Count == 0) { res = createExpr.Expression; } else { body.Add(allocatedInst); res = Ast.Block(body); } res = Ast.Block(new ParameterExpression[] { allocatedInst }, res); additionalRestrictions = initCall.Restrictions; } return(BindingHelpers.AddDynamicTestAndDefer( call, new DynamicMetaObject( res, self.Restrictions.Merge(additionalRestrictions) ), ArrayUtils.Insert(this, args), valInfo )); }
internal static DynamicMetaObject Call(DynamicMetaObjectBinder /*!*/ call, DynamicMetaObject target, DynamicMetaObject /*!*/[] /*!*/ args) { Assert.NotNull(call, args); Assert.NotNullItems(args); if (target.NeedsDeferral()) { return(call.Defer(ArrayUtils.Insert(target, args))); } foreach (DynamicMetaObject mo in args) { if (mo.NeedsDeferral()) { RestrictTypes(args); return(call.Defer( ArrayUtils.Insert(target, args) )); } } DynamicMetaObject self = target.Restrict(target.GetLimitType()); ValidationInfo valInfo = BindingHelpers.GetValidationInfo(target); PythonType pt = DynamicHelpers.GetPythonType(target.Value); PythonContext pyContext = PythonContext.GetPythonContext(call); // look for __call__, if it's present dispatch to it. Otherwise fall back to the // default binder PythonTypeSlot callSlot; if (!typeof(Delegate).IsAssignableFrom(target.GetLimitType()) && pt.TryResolveSlot(pyContext.SharedContext, "__call__", out callSlot)) { ConditionalBuilder cb = new ConditionalBuilder(call); callSlot.MakeGetExpression( pyContext.Binder, PythonContext.GetCodeContext(call), self, GetPythonType(self), cb ); if (!cb.IsFinal) { cb.FinishCondition(GetCallError(call, self)); } Expression[] callArgs = ArrayUtils.Insert( PythonContext.GetCodeContext(call), cb.GetMetaObject().Expression, DynamicUtils.GetExpressions(args) ); Expression body = DynamicExpression.Dynamic( PythonContext.GetPythonContext(call).Invoke( BindingHelpers.GetCallSignature(call) ), typeof(object), callArgs ); body = Ast.TryFinally( Ast.Block( Ast.Call(typeof(PythonOps).GetMethod(nameof(PythonOps.FunctionPushFrame)), Ast.Constant(pyContext)), body ), Ast.Call(typeof(PythonOps).GetMethod(nameof(PythonOps.FunctionPopFrame))) ); return(BindingHelpers.AddDynamicTestAndDefer( call, new DynamicMetaObject(body, self.Restrictions.Merge(BindingRestrictions.Combine(args))), args, valInfo )); } return(null); }
public override DynamicMetaObject /*!*/ FallbackCreateInstance(DynamicMetaObject /*!*/ target, DynamicMetaObject /*!*/[] /*!*/ args, DynamicMetaObject errorSuggestion) { return(_fallback.InvokeFallback(target, args, BindingHelpers.GetCallSignature(this), errorSuggestion)); }
private DynamicMetaObject /*!*/ MakeSelfCall(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] /*!*/ args) { BindingRestrictions selfRestrict = Restrictions.Merge( BindingRestrictionsHelpers.GetRuntimeTypeRestriction( Expression, LimitType ) ).Merge( BindingRestrictions.GetExpressionRestriction( Value.MakeBoundFunctionTest( AstUtils.Convert(Expression, typeof(BuiltinFunction)) ) ) ); Expression instance = Ast.Call( typeof(PythonOps).GetMethod("GetBuiltinFunctionSelf"), AstUtils.Convert( Expression, typeof(BuiltinFunction) ) ); DynamicMetaObject self = GetInstance(instance, CompilerHelpers.GetType(Value.BindingSelf)); return(Value.MakeBuiltinFunctionCall( call, codeContext, this, ArrayUtils.Insert(self, args), true, // has self selfRestrict, (newArgs) => { CallSignature signature = BindingHelpers.GetCallSignature(call); DynamicMetaObject res; PythonContext state = PythonContext.GetPythonContext(call); BindingTarget target; PythonOverloadResolver resolver; if (Value.IsReversedOperator) { resolver = new PythonOverloadResolver( state.Binder, newArgs, GetReversedSignature(signature), codeContext ); } else { resolver = new PythonOverloadResolver( state.Binder, self, args, signature, codeContext ); } res = state.Binder.CallMethod( resolver, Value.Targets, self.Restrictions, Value.Name, NarrowingLevel.None, Value.IsBinaryOperator ? PythonNarrowing.BinaryOperator : NarrowingLevel.All, out target ); return BindingHelpers.CheckLightThrow(call, res, target); } )); }
private DynamicMetaObject /*!*/ InvokeWorker(DynamicMetaObjectBinder /*!*/ call, Expression /*!*/ codeContext, DynamicMetaObject /*!*/[] /*!*/ args) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "BuiltinFunc Invoke " + Value.DeclaringType.FullName + "." + Value.Name + " with " + args.Length + " args " + Value.IsUnbound); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "BuiltinFunction " + Value.Targets.Count + ", " + Value.Targets[0].GetParameters().Length); PerfTrack.NoteEvent(PerfTrack.Categories.BindingSlow, "BuiltinFunction " + BindingHelpers.GetCallSignature(call)); if (this.NeedsDeferral()) { return(call.Defer(ArrayUtils.Insert(this, args))); } for (int i = 0; i < args.Length; i++) { if (args[i].NeedsDeferral()) { return(call.Defer(ArrayUtils.Insert(this, args))); } } if (Value.IsUnbound) { return(MakeSelflessCall(call, codeContext, args)); } else { return(MakeSelfCall(call, codeContext, args)); } }
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) )); } }