public ConversionBinder(BinderState/*!*/ state, Type/*!*/ type, ConversionResultKind resultKind) : base(type, resultKind == ConversionResultKind.ExplicitCast || resultKind == ConversionResultKind.ExplicitTry) { Assert.NotNull(state, type); _state = state; _kind = resultKind; }
internal AstGenerator(AstGenerator/*!*/ parent, string name, bool generator, bool print) : this(name, generator, false) { Assert.NotNull(parent); _context = parent.Context; _binderState = parent.BinderState; _document = _context.SourceUnit.Document; }
internal AstGenerator(CompilerContext/*!*/ context, SourceSpan span, string name, bool generator, bool print) : this(name, generator, print) { Assert.NotNull(context); _context = context; _binderState = new BinderState(Binder); _document = _context.SourceUnit.Document; }
/// <summary> /// Backwards compatible Convert for the old sites that need to flow CodeContext /// </summary> public static Expression/*!*/ Convert(Expression/*!*/ codeContext, BinderState/*!*/ binder, Type/*!*/ type, ConversionResultKind resultKind, Expression/*!*/ target) { return Ast.Dynamic( binder.Convert(type, resultKind), type, target ); }
public static Expression/*!*/ Get(Expression/*!*/ codeContext, BinderState/*!*/ binder, Type/*!*/ resultType, string/*!*/ name, Expression/*!*/ target) { return Ast.Dynamic( binder.GetMember(name), resultType, target, codeContext ); }
public static Expression/*!*/ Operation(BinderState/*!*/ binder, Type/*!*/ resultType, string/*!*/ operation, Expression arg0) { return Ast.Dynamic( new PythonOperationBinder( binder, operation ), resultType, arg0 ); }
public static Expression/*!*/ Convert(BinderState/*!*/ binder, Type/*!*/ type, ConversionResultKind resultKind, Expression/*!*/ target) { return Ast.Dynamic( new ConversionBinder( binder, type, resultKind ), type, target ); }
public static DynamicMetaObjectBinder UnaryOperationBinder(BinderState state, PythonOperationKind operatorName) { ExpressionType? et = GetExpressionTypeFromUnaryOperator(operatorName); if (et == null) { return state.Operation( operatorName ); } return state.UnaryOperation(et.Value); }
internal static MethodCallExpression MakeTryGetTypeMember(BinderState/*!*/ binderState, PythonTypeSlot dts, ParameterExpression tmp, Expression instance, Expression pythonType) { return Ast.Call( TypeInfo._PythonOps.SlotTryGetBoundValue, Ast.Constant(binderState.Context), AstUtils.Convert(Utils.WeakConstant(dts), typeof(PythonTypeSlot)), AstUtils.Convert(instance, typeof(object)), AstUtils.Convert( pythonType, typeof(PythonType) ), tmp ); }
public static DynamicMetaObjectBinder/*!*/ BinaryOperationRetType(BinderState/*!*/ state, PythonOperationKind operatorName, Type retType) { return new ComboBinder( new BinderMappingInfo( BinaryOperationBinder(state, operatorName), ParameterMappingInfo.Parameter(0), ParameterMappingInfo.Parameter(1) ), new BinderMappingInfo( state.Convert(retType, ConversionResultKind.ExplicitCast), ParameterMappingInfo.Action(0) ) ); }
/// <summary> /// Trys to get the BuiltinFunction for the given name on the type of the provided MetaObject. /// /// Succeeds if the MetaObject is a BuiltinFunction or BuiltinMethodDescriptor. /// </summary> internal static bool TryGetStaticFunction(BinderState/*!*/ state, SymbolId op, DynamicMetaObject/*!*/ mo, out BuiltinFunction function) { PythonType type = MetaPythonObject.GetPythonType(mo); function = null; if (op != SymbolId.Empty) { PythonTypeSlot xSlot; object val; if (type.TryResolveSlot(state.Context, op, out xSlot) && xSlot.TryGetValue(state.Context, null, type, out val)) { function = TryConvertToBuiltinFunction(val); if (function == null) return false; } } return true; }
internal static MethodCallExpression MakeTryGetTypeMember(BinderState/*!*/ binderState, PythonTypeSlot dts, Expression self, ParameterExpression tmp) { return MakeTryGetTypeMember( binderState, dts, tmp, self, Ast.Property( Ast.Convert( self, typeof(IPythonObject)), TypeInfo._IPythonObject.PythonType ) ); }
public static Expression/*!*/ Invoke(BinderState/*!*/ binder, Type/*!*/ resultType, CallSignature signature, params Expression/*!*/[]/*!*/ args) { PythonInvokeBinder invoke = new PythonInvokeBinder(binder, signature); switch(args.Length) { case 0: return Ast.Dynamic(invoke, resultType, AstUtils.CodeContext()); case 1: return Ast.Dynamic(invoke, resultType, AstUtils.CodeContext(), args[0]); case 2: return Ast.Dynamic(invoke, resultType, AstUtils.CodeContext(), args[0], args[1]); case 3: return Ast.Dynamic(invoke, resultType, AstUtils.CodeContext(), args[0], args[1], args[2]); default: return Ast.Dynamic( invoke, resultType, new ReadOnlyCollection<Expression>(ArrayUtils.Insert(AstUtils.CodeContext(), args)) ); } }
private DynamicMetaObject/*!*/ FallbackGetMember(DynamicMetaObjectBinder member, BinderState state) { MemberTracker tt = MemberTracker.FromMemberInfo(Value.UnderlyingSystemType); if (member is IPythonSite) { // bind the .NET members string memberName = GetGetMemberName(member); return state.Binder.GetMember( memberName, new DynamicMetaObject( Ast.Constant(tt), BindingRestrictions.Empty, tt ), Ast.Constant(state.Context), BindingHelpers.IsNoThrow(member) ); } // let the calling language bind the .NET members return GetMemberFallback(this, member, BinderState.GetCodeContext(member)); }
private DynamicMetaObject/*!*/ GetFallbackGet(DynamicMetaObjectBinder/*!*/ member, BinderState/*!*/ state, Expression codeContext) { string memberName = GetGetMemberName(member); DynamicMetaObject res = new DynamicMetaObject( FallbackGetMember(member, state).Expression, BindingRestrictions.GetInstanceRestriction(Expression, Value).Merge(Restrictions) ); if (codeContext != null && Value.IsHiddenMember(memberName)) { res = BindingHelpers.FilterShowCls( codeContext, member, res, Ast.Throw( Ast.Call( typeof(PythonOps).GetMethod("AttributeErrorForMissingAttribute", new Type[] { typeof(string), typeof(SymbolId) }), AstUtils.Constant(Value.Name), AstUtils.Constant(SymbolTable.StringToId(memberName)) ) ) ); } return res; }
public PythonGetMemberBinder(BinderState/*!*/ binder, string/*!*/ name) { _state = binder; _name = name; }
public CompatibilityGetMember(BinderState/*!*/ binder, string/*!*/ name) : this(binder, name, false) { }
internal AstGenerator(AstGenerator/*!*/ parent, string name, bool generator, string profilerName) : this(name, generator, profilerName, false) { Assert.NotNull(parent); _context = parent.Context; _binderState = parent.BinderState; _parent = parent; _document = _context.SourceUnit.Document ?? Ast.SymbolDocument(name, PythonContext.LanguageGuid, PythonContext.VendorGuid); _profiler = parent._profiler; _globals = parent._globals; }
public static Expression/*!*/ Invoke(Expression codeContext, BinderState/*!*/ binder, Type/*!*/ resultType, CallSignature signature, params Expression/*!*/[]/*!*/ args) { return Ast.Dynamic( binder.Invoke( signature ), resultType, ArrayUtils.Insert(codeContext, args) ); }
/// <summary> /// Used for conversions to bool /// </summary> private static Expression/*!*/ GetConvertByLengthBody(BinderState/*!*/ state, Expression/*!*/ call) { Assert.NotNull(state, call); Expression callAsInt = call; if (call.Type != typeof(int)) { callAsInt = Ast.Dynamic( state.Convert(typeof(int), ConversionResultKind.ExplicitCast), typeof(int), call ); } return Ast.NotEqual(callAsInt, AstUtils.Constant(0)); }
private static DynamicMetaObject MakeGetItemIterable(DynamicMetaObject metaUserObject, BinderState state, PythonTypeSlot pts, string method) { ParameterExpression tmp = Ast.Parameter(typeof(object), "getitemVal"); return new DynamicMetaObject( Expression.Block( new[] { tmp }, Expression.Call( typeof(PythonOps).GetMethod(method), Ast.Block( MetaPythonObject.MakeTryGetTypeMember( state, pts, tmp, metaUserObject.Expression, Ast.Call( typeof(DynamicHelpers).GetMethod("GetPythonType"), AstUtils.Convert( metaUserObject.Expression, typeof(object) ) ) ), tmp ), AstUtils.Constant( CallSite<Func<CallSite, CodeContext, object, int, object>>.Create( new PythonInvokeBinder(state, new CallSignature(1)) ) ) ) ), metaUserObject.Restrictions ); }
internal AstGenerator(CompilationMode mode, CompilerContext/*!*/ context, SourceSpan span, string name, bool generator, bool print) : this(name, generator, null, print) { Assert.NotNull(context); _context = context; _binderState = new BinderState(Binder); _document = _context.SourceUnit.Document; LanguageContext pc = context.SourceUnit.LanguageContext; switch (mode) { case CompilationMode.Collectable: _globals = new ArrayGlobalAllocator(pc); break; case CompilationMode.Lookup: _globals = new DictionaryGlobalAllocator(); break; case CompilationMode.ToDisk: _globals = new SavableGlobalAllocator(pc); break; case CompilationMode.Uncollectable: _globals = new StaticGlobalAllocator(pc, name); break; } PythonOptions po = (pc.Options as PythonOptions); Assert.NotNull(po); if (po.EnableProfiler && mode != CompilationMode.ToDisk) { _profiler = Profiler.GetProfiler(PythonContext); if (mode == CompilationMode.Lookup) { _profilerName = NameForExec; } } }
public PythonSetSliceBinder(BinderState/*!*/ state) { _state = state; }
private static void GetOpreatorMethods(DynamicMetaObject/*!*/[]/*!*/ types, PythonOperationKind oper, BinderState state, out SlotOrFunction fbinder, out SlotOrFunction rbinder, out PythonTypeSlot fSlot, out PythonTypeSlot rSlot) { oper = NormalizeOperator(oper); oper &= ~PythonOperationKind.InPlace; SymbolId op, rop; if (!IsReverseOperator(oper)) { op = Symbols.OperatorToSymbol(oper); rop = Symbols.OperatorToReversedSymbol(oper); } else { // coming back after coercion, just try reverse operator. rop = Symbols.OperatorToSymbol(oper); op = Symbols.OperatorToReversedSymbol(oper); } fSlot = null; rSlot = null; PythonType fParent, rParent; if (oper == PythonOperationKind.Multiply && IsSequence(types[0]) && !PythonOps.IsNonExtensibleNumericType(types[1].GetLimitType())) { // class M: // def __rmul__(self, other): // print "CALLED" // return 1 // // print [1,2] * M() // // in CPython this results in a successful call to __rmul__ on the type ignoring the forward // multiplication. But calling the __mul__ method directly does NOT return NotImplemented like // one might expect. Therefore we explicitly convert the MetaObject argument into an Index // for binding purposes. That allows this to work at multiplication time but not with // a direct call to __mul__. DynamicMetaObject[] newTypes = new DynamicMetaObject[2]; newTypes[0] = types[0]; newTypes[1] = new DynamicMetaObject( Ast.New( typeof(Index).GetConstructor(new Type[] { typeof(object) }), AstUtils.Convert(types[1].Expression, typeof(object)) ), BindingRestrictions.Empty ); types = newTypes; } if (!SlotOrFunction.TryGetBinder(state, types, op, SymbolId.Empty, out fbinder, out fParent)) { foreach (PythonType pt in MetaPythonObject.GetPythonType(types[0]).ResolutionOrder) { if (pt.TryLookupSlot(state.Context, op, out fSlot)) { fParent = pt; break; } } } if (!SlotOrFunction.TryGetBinder(state, types, SymbolId.Empty, rop, out rbinder, out rParent)) { foreach (PythonType pt in MetaPythonObject.GetPythonType(types[1]).ResolutionOrder) { if (pt.TryLookupSlot(state.Context, rop, out rSlot)) { rParent = pt; break; } } } if (fParent != null && (rbinder.Success || rSlot != null) && rParent != fParent && rParent.IsSubclassOf(fParent)) { // Python says if x + subx and subx defines __r*__ we should call r*. fbinder = SlotOrFunction.Empty; fSlot = null; } if (!fbinder.Success && !rbinder.Success && fSlot == null && rSlot == null) { if (op == Symbols.OperatorTrueDivide || op == Symbols.OperatorReverseTrueDivide) { // true div on a type which doesn't support it, go ahead and try normal divide PythonOperationKind newOp = op == Symbols.OperatorTrueDivide ? PythonOperationKind.Divide : PythonOperationKind.ReverseDivide; GetOpreatorMethods(types, newOp, state, out fbinder, out rbinder, out fSlot, out rSlot); } } }
internal AstGenerator(AstGenerator/*!*/ parent, string name, bool generator, string profilerName) : this(name, generator, profilerName, false) { Assert.NotNull(parent); _context = parent.Context; _binderState = parent.BinderState; _parent = parent; _document = _context.SourceUnit.Document; _profiler = parent._profiler; _globals = parent._globals; }
private static bool MakeOneTarget(BinderState/*!*/ state, SlotOrFunction/*!*/ target, PythonTypeSlot slotTarget, ConditionalBuilder/*!*/ bodyBuilder, bool reverse, DynamicMetaObject/*!*/[]/*!*/ types) { if (target == SlotOrFunction.Empty && slotTarget == null) return true; if (slotTarget != null) { MakeSlotCall(state, types, bodyBuilder, slotTarget, reverse); return true; } else if (target.MaybeNotImplemented) { Debug.Assert(target.ReturnType == typeof(object)); ParameterExpression tmp = Ast.Variable(typeof(object), "slot"); bodyBuilder.AddVariable(tmp); bodyBuilder.AddCondition( Ast.NotEqual( Ast.Assign( tmp, target.Target.Expression ), Ast.Property(null, typeof(PythonOps).GetProperty("NotImplemented")) ), tmp ); return true; } else { bodyBuilder.FinishCondition(target.Target.Expression); return false; } }
public CompatibilityGetMember(BinderState/*!*/ binder, string/*!*/ name, bool ignoreCase) : base(name, ignoreCase) { _state = binder; }
private static void MakeSlotCall(BinderState/*!*/ state, DynamicMetaObject/*!*/[]/*!*/ types, ConditionalBuilder/*!*/ bodyBuilder, PythonTypeSlot/*!*/ slotTarget, bool reverse) { Debug.Assert(slotTarget != null); Expression self, other; if (reverse) { self = types[1].Expression; other = types[0].Expression; } else { self = types[0].Expression; other = types[1].Expression; } MakeSlotCallWorker(state, slotTarget, self, bodyBuilder, other); }
public PythonGetMemberBinder(BinderState/*!*/ binder, string/*!*/ name, bool isNoThrow) : this(binder, name) { _options = isNoThrow ? GetMemberOptions.IsNoThrow : GetMemberOptions.None; }
private static void MakeSlotCallWorker(BinderState/*!*/ state, PythonTypeSlot/*!*/ slotTarget, Expression/*!*/ self, ConditionalBuilder/*!*/ bodyBuilder, params Expression/*!*/[]/*!*/ args) { // Generate: // // SlotTryGetValue(context, slot, selfType, out callable) && (tmp=callable(args)) != NotImplemented) ? // tmp : // RestOfOperation // ParameterExpression callable = Ast.Variable(typeof(object), "slot"); ParameterExpression tmp = Ast.Variable(typeof(object), "slot"); bodyBuilder.AddCondition( Ast.AndAlso( Ast.Call( typeof(PythonOps).GetMethod("SlotTryGetValue"), AstUtils.Constant(state.Context), AstUtils.Convert(Utils.WeakConstant(slotTarget), typeof(PythonTypeSlot)), AstUtils.Convert(self, typeof(object)), Ast.Call( typeof(DynamicHelpers).GetMethod("GetPythonType"), AstUtils.Convert(self, typeof(object)) ), callable ), Ast.NotEqual( Ast.Assign( tmp, Ast.Dynamic( state.Invoke( new CallSignature(args.Length) ), typeof(object), ArrayUtils.Insert(AstUtils.Constant(state.Context), (Expression)callable, args) ) ), Ast.Property(null, typeof(PythonOps).GetProperty("NotImplemented")) ) ), tmp ); bodyBuilder.AddVariable(callable); bodyBuilder.AddVariable(tmp); }