private DynamicMetaObject/*!*/ MakeMemberAccess(DynamicMetaObjectBinder/*!*/ member, string name, MemberAccess access, params DynamicMetaObject/*!*/[]/*!*/ args) { DynamicMetaObject self = Restrict(typeof(OldInstance)); CustomOldClassDictionaryStorage dict; int key = GetCustomStorageSlot(name, out dict); if (key == -1) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldInstance " + access + " NoOptimized"); return MakeDynamicMemberAccess(member, name, access, args); } ParameterExpression tmp = Ast.Variable(typeof(object), "dict"); Expression target; ValidationInfo test = new ValidationInfo( Ast.NotEqual( Ast.Assign( tmp, Ast.Call( typeof(PythonOps).GetMethod("OldInstanceGetOptimizedDictionary"), self.Expression, AstUtils.Constant(dict.KeyVersion) ) ), AstUtils.Constant(null) ) ); PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldInstance " + access + " Optimized"); switch (access) { case MemberAccess.Invoke: ParameterExpression value = Ast.Variable(typeof(object), "value"); target = Ast.Block( new[] { value }, Ast.Condition( Ast.Call( typeof(PythonOps).GetMethod("TryOldInstanceDictionaryGetValueHelper"), tmp, Ast.Constant(key), AstUtils.Convert(Expression, typeof(object)), value ), AstUtils.Convert( ((InvokeMemberBinder)member).FallbackInvoke(new DynamicMetaObject(value, BindingRestrictions.Empty), args, null).Expression, typeof(object) ), AstUtils.Convert( ((InvokeMemberBinder)member).FallbackInvokeMember(self, args).Expression, typeof(object) ) ) ); break; case MemberAccess.Get: // BUG: There's a missing Fallback path here that's always been present even // in the version that used rules. target = Ast.Call( typeof(PythonOps).GetMethod("OldInstanceDictionaryGetValueHelper"), tmp, AstUtils.Constant(key), AstUtils.Convert(Expression, typeof(object)) ); break; case MemberAccess.Set: target = Ast.Call( typeof(PythonOps).GetMethod("OldInstanceDictionarySetExtraValue"), tmp, AstUtils.Constant(key), AstUtils.Convert(args[1].Expression, typeof(object)) ); break; case MemberAccess.Delete: target = Ast.Call( typeof(PythonOps).GetMethod("OldInstanceDeleteCustomMember"), AstUtils.Constant(PythonContext.GetPythonContext(member).SharedContext), AstUtils.Convert(Expression, typeof(OldInstance)), AstUtils.Constant(name) ); break; default: throw new InvalidOperationException(); } return BindingHelpers.AddDynamicTestAndDefer( member, new DynamicMetaObject( target, BindingRestrictions.Combine(args).Merge(self.Restrictions) ), args, test, tmp ); }
public SetBindingInfo(SetMemberBinder/*!*/ action, DynamicMetaObject/*!*/[]/*!*/ args, ConditionalBuilder/*!*/ body, ValidationInfo/*!*/ validation) : base(args, body, validation) { Action = action; }
public GetBindingInfo(DynamicMetaObjectBinder/*!*/ action, DynamicMetaObject/*!*/[]/*!*/ args, ParameterExpression/*!*/ self, ParameterExpression/*!*/ result, ConditionalBuilder/*!*/ body, ValidationInfo/*!*/ validationInfo) : base(args, body, validationInfo) { Action = action; Self = self; Result = result; }
private DynamicMetaObject/*!*/ MakeAbstractInstantiationError(DynamicMetaObjectBinder/*!*/ call, ArgumentValues/*!*/ ai, ValidationInfo/*!*/ valInfo) { CodeContext context = PythonContext.GetPythonContext(call).SharedContext; string message = Value.GetAbstractErrorMessage(context); Debug.Assert(message != null); return BindingHelpers.AddDynamicTestAndDefer( call, new DynamicMetaObject( Ast.Throw( Ast.New( typeof(ArgumentTypeException).GetConstructor(new Type[] { typeof(string) }), AstUtils.Constant(message) ), typeof(object) ), GetErrorRestrictions(ai) ), ai.Arguments, valInfo ); }
public MemberBindingInfo(DynamicMetaObject/*!*/[]/*!*/ args, ConditionalBuilder/*!*/ body, ValidationInfo/*!*/ validation) { Body = body; Validation = validation; Args = args; }
private DynamicMetaObject/*!*/ MakeIncorrectArgumentsForCallError(DynamicMetaObjectBinder/*!*/ call, ArgumentValues/*!*/ ai, ValidationInfo/*!*/ valInfo) { string message; if (Value.IsSystemType) { if (Value.UnderlyingSystemType.GetConstructors().Length == 0) { // this is a type we can't create ANY instances of, give the user a half-way decent error message message = "cannot create instances of " + Value.Name; } else { message = InstanceOps.ObjectNewNoParameters; } } else { message = InstanceOps.ObjectNewNoParameters; } return BindingHelpers.AddDynamicTestAndDefer( call, new DynamicMetaObject( call.Throw( Ast.New( typeof(TypeErrorException).GetConstructor(new Type[] { typeof(string) }), AstUtils.Constant(message) ) ), GetErrorRestrictions(ai) ), ai.Arguments, valInfo ); }
private DynamicMetaObject/*!*/ MakeGenericTypeDefinitionError(DynamicMetaObjectBinder/*!*/ call, ArgumentValues/*!*/ ai, ValidationInfo/*!*/ valInfo) { Debug.Assert(Value.IsSystemType); string message = "cannot create instances of " + Value.Name + " because it is a generic type definition"; return BindingHelpers.AddDynamicTestAndDefer( call, new DynamicMetaObject( call.Throw( Ast.New( typeof(TypeErrorException).GetConstructor(new Type[] { typeof(string) }), AstUtils.Constant(message) ), typeof(object) ), GetErrorRestrictions(ai) ), ai.Arguments, valInfo ); }
internal static DynamicMetaObject/*!*/ AddDynamicTestAndDefer(DynamicMetaObjectBinder/*!*/ operation, DynamicMetaObject/*!*/ res, DynamicMetaObject/*!*/[] args, ValidationInfo typeTest, Type deferType, params ParameterExpression[] temps) { if (typeTest != null) { if (typeTest.Test != null) { // add the test and a validator if persent Expression defer = operation.GetUpdateExpression(deferType ?? typeof(object)); Type bestType = BindingHelpers.GetCompatibleType(defer.Type, res.Expression.Type); res = new DynamicMetaObject( Ast.Condition( typeTest.Test, AstUtils.Convert(res.Expression, bestType), AstUtils.Convert(defer, bestType) ), res.Restrictions ); } } if (temps.Length > 0) { // finally add the scoped variables res = new DynamicMetaObject( Ast.Block(temps, res.Expression), res.Restrictions, null ); } return res; }
internal static DynamicMetaObject/*!*/ AddDynamicTestAndDefer(DynamicMetaObjectBinder/*!*/ operation, DynamicMetaObject/*!*/ res, DynamicMetaObject/*!*/[] args, ValidationInfo typeTest, params ParameterExpression[] temps) { return AddDynamicTestAndDefer(operation, res, args, typeTest, null, temps); }
/// <summary> /// Transforms an invoke member into a Python GetMember/Invoke. The caller should /// verify that the given attribute is not resolved against a normal .NET class /// before calling this. If it is a normal .NET member then a fallback InvokeMember /// is preferred. /// </summary> internal static DynamicMetaObject/*!*/ GenericInvokeMember(InvokeMemberBinder/*!*/ action, ValidationInfo valInfo, DynamicMetaObject target, DynamicMetaObject/*!*/[]/*!*/ args) { if (target.NeedsDeferral()) { return action.Defer(args); } return AddDynamicTestAndDefer(action, action.FallbackInvoke( new DynamicMetaObject( Binders.Get( PythonContext.GetCodeContext(action), PythonContext.GetPythonContext(action), typeof(object), action.Name, target.Expression ), BindingRestrictionsHelpers.GetRuntimeTypeRestriction(target) ), args, null ), 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); Expression body; 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) ); body = Ast.Dynamic( PythonContext.GetPythonContext(call).Invoke( BindingHelpers.GetCallSignature(call) ), typeof(object), callArgs ); body = Ast.TryFinally( Ast.Block( Ast.Call(typeof(PythonOps).GetMethod("FunctionPushFrame"), Ast.Constant(pyContext)), body ), Ast.Call(typeof(PythonOps).GetMethod("FunctionPopFrame")) ); return(BindingHelpers.AddDynamicTestAndDefer( call, new DynamicMetaObject(body, self.Restrictions.Merge(BindingRestrictions.Combine(args))), args, valInfo )); } return(null); }
public MetaGetBinderHelper(MetaPythonType type, DynamicMetaObjectBinder member, Expression codeContext, ValidationInfo validationInfo, ValidationInfo metaValidation) : base(type.Value, PythonContext.GetPythonContext(member).SharedContext, GetGetMemberName(member)) { _member = member; _codeContext = codeContext; _type = type; _cb = new ConditionalBuilder(member); _symName = GetGetMemberName(member); _restrictedSelf = new DynamicMetaObject( AstUtils.Convert(Expression, Value.GetType()), Restrictions.Merge(BindingRestrictions.GetInstanceRestriction(Expression, Value)), Value ); _state = PythonContext.GetPythonContext(member); _valInfo = validationInfo; _metaValInfo = metaValidation; }