/// <summary> /// Backwards compatible Convert for the old sites that need to flow CodeContext /// </summary> public static Expression/*!*/ Convert(Expression/*!*/ codeContext, PythonContext/*!*/ binder, Type/*!*/ type, ConversionResultKind resultKind, Expression/*!*/ target) { return Ast.Dynamic( binder.Convert(type, resultKind), type, target ); }
public static Expression/*!*/ Get(Expression/*!*/ codeContext, PythonContext/*!*/ binder, Type/*!*/ resultType, string/*!*/ name, Expression/*!*/ target) { return Ast.Dynamic( binder.GetMember(name), resultType, target, codeContext ); }
public static bool ShouldWarn(PythonContext/*!*/ context, MethodBase/*!*/ method, out WarningInfo info) { Assert.NotNull(method); ObsoleteAttribute[] os = (ObsoleteAttribute[])method.GetCustomAttributes(typeof(ObsoleteAttribute), true); if (os.Length > 0) { info = new WarningInfo( PythonExceptions.DeprecationWarning, String.Format("{0}.{1} has been obsoleted. {2}", NameConverter.GetTypeName(method.DeclaringType), method.Name, os[0].Message ) ); return true; } if (context.PythonOptions.WarnPython30) { Python3WarningAttribute[] py3kwarnings = (Python3WarningAttribute[])method.GetCustomAttributes(typeof(Python3WarningAttribute), true); if (py3kwarnings.Length > 0) { info = new WarningInfo( PythonExceptions.DeprecationWarning, py3kwarnings[0].Message ); return true; } } #if !SILVERLIGHT // no apartment states on Silverlight if (method.DeclaringType == typeof(Thread)) { if (method.Name == "Sleep") { info = new WarningInfo( PythonExceptions.RuntimeWarning, "Calling Thread.Sleep on an STA thread doesn't pump messages. Use Thread.CurrentThread.Join instead.", Expression.Equal( Expression.Call( Expression.Property( null, typeof(Thread).GetProperty("CurrentThread") ), typeof(Thread).GetMethod("GetApartmentState") ), AstUtils.Constant(ApartmentState.STA) ), () => Thread.CurrentThread.GetApartmentState() == ApartmentState.STA ); return true; } } #endif info = null; return false; }
public static DynamicMetaObjectBinder BinaryOperationBinder(PythonContext state, PythonOperationKind operatorName) { ExpressionType? et = GetExpressionTypeFromBinaryOperator(operatorName); if (et == null) { return state.Operation( operatorName ); } return state.BinaryOperation(et.Value); }
internal static MethodCallExpression MakeTryGetTypeMember(PythonContext/*!*/ PythonContext, PythonTypeSlot dts, ParameterExpression tmp, Expression instance, Expression pythonType) { return Ast.Call( PythonTypeInfo._PythonOps.SlotTryGetBoundValue, AstUtils.Constant(PythonContext.SharedContext), AstUtils.Convert(Utils.WeakConstant(dts), typeof(PythonTypeSlot)), AstUtils.Convert(instance, typeof(object)), AstUtils.Convert( pythonType, typeof(PythonType) ), tmp ); }
internal static MethodCallExpression MakeTryGetTypeMember(PythonContext/*!*/ PythonContext, PythonTypeSlot dts, Expression self, ParameterExpression tmp) { return MakeTryGetTypeMember( PythonContext, dts, tmp, self, Ast.Property( Ast.Convert( self, typeof(IPythonObject)), PythonTypeInfo._IPythonObject.PythonType ) ); }
/// <summary> /// Tries 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(PythonContext/*!*/ state, string op, DynamicMetaObject/*!*/ mo, out BuiltinFunction function) { PythonType type = MetaPythonObject.GetPythonType(mo); function = null; if (!String.IsNullOrEmpty(op)) { PythonTypeSlot xSlot; object val; if (type.TryResolveSlot(state.SharedContext, op, out xSlot) && xSlot.TryGetValue(state.SharedContext, null, type, out val)) { function = TryConvertToBuiltinFunction(val); if (function == null) return false; } } return true; }
public PythonBinder(ScriptDomainManager manager, PythonContext/*!*/ pythonContext, CodeContext context) : base(manager) { ContractUtils.RequiresNotNull(pythonContext, "pythonContext"); _context = pythonContext; if (context != null) { context.LanguageContext.DomainManager.AssemblyLoaded += new EventHandler<AssemblyLoadedEventArgs>(DomainManager_AssemblyLoaded); foreach (Assembly asm in pythonContext.DomainManager.GetLoadedAssemblyList()) { DomainManager_AssemblyLoaded(this, new AssemblyLoadedEventArgs(asm)); } } EmptyGetMemberAction = OldGetMemberAction.Make(this, String.Empty); }
protected Callable(PythonContext/*!*/ binder, PythonIndexType op) { Assert.NotNull(binder); _binder = binder; _op = op; }
private bool ShouldInterpret(PythonContext pc) { return(pc.ShouldInterpret((PythonCompilerOptions)Ast.CompilerContext.Options, Ast.CompilerContext.SourceUnit)); }
private static DynamicMetaObject MakeUnindexableError(DynamicMetaObjectBinder operation, PythonIndexType op, DynamicMetaObject/*!*/[] types, DynamicMetaObject indexedType, PythonContext state) { DynamicMetaObject[] newTypes = (DynamicMetaObject[])types.Clone(); newTypes[0] = indexedType; PythonTypeSlot dummySlot; if (op != PythonIndexType.GetItem && op != PythonIndexType.GetSlice && DynamicHelpers.GetPythonType(indexedType.Value).TryResolveSlot(state.SharedContext, "__getitem__", out dummySlot)) { // object supports indexing but not setting/deletion if (op == PythonIndexType.SetItem || op == PythonIndexType.SetSlice) { return TypeError(operation, "'{0}' object does not support item assignment", newTypes); } else { return TypeError(operation, "'{0}' object doesn't support item deletion", newTypes); } } return TypeError(operation, "'{0}' object is unsubscriptable", newTypes); }
public PythonService(PythonContext /*!*/ context, ScriptEngine /*!*/ engine) { Assert.NotNull(context, engine); _context = context; _engine = engine; }
public PythonSetSliceBinder(PythonContext /*!*/ context) { _context = context; }
public override DynamicMetaObject/*!*/ MakeRule(DynamicMetaObjectBinder/*!*/ metaBinder, PythonContext/*!*/ binder, DynamicMetaObject/*!*/[]/*!*/ args) { DynamicMetaObject[] tupleArgs = Callable.GetTupleArguments(args); return Callable.CompleteRuleTarget(metaBinder, tupleArgs, delegate() { PythonTypeSlot indexSlot; if (args[1].GetLimitType() != typeof(Slice) && GetTypeAt(1).TryResolveSlot(binder.SharedContext, "__index__", out indexSlot)) { args[1] = new DynamicMetaObject( DynamicExpression.Dynamic( binder.Convert( typeof(int), ConversionResultKind.ExplicitCast ), typeof(int), DynamicExpression.Dynamic( binder.InvokeNone, typeof(object), AstUtils.Constant(binder.SharedContext), Binders.Get( AstUtils.Constant(binder.SharedContext), binder, typeof(object), "__index__", args[1].Expression ) ) ), BindingRestrictions.Empty ); return Callable.CompleteRuleTarget(metaBinder, tupleArgs, null); } return null; }); }
private static DynamicExpression/*!*/ HashConvertToInt(PythonContext/*!*/ state, Expression/*!*/ expression) { return DynamicExpression.Dynamic( state.Convert( typeof(int), ConversionResultKind.ExplicitCast ), typeof(int), expression ); }
private static PythonSignalState MakeNtSignalState(PythonContext context) { return(new NtSignalState(context)); }
private static PythonSignalState MakePosixSignalState(PythonContext context) { // Use SimpleSignalState until the real Posix one is written return(new SimpleSignalState(context)); }
// Structural Comparison Helpers private static int StructuralCompare(CodeContext /*!*/ context, IStructuralComparable x, object y) { return(x.CompareTo(y, PythonContext.GetContext(context).GetComparer(null, null))); }
public static void PerformModuleReload(PythonContext /*!*/ context, PythonDictionary /*!*/ dict) { context.SetModuleState(_PythonSignalStateKey, MakeSignalState(context)); }
public static bool StructuralInequalityMethod <T>(CodeContext /*!*/ context, T x, [NotNull] T y) where T : IStructuralEquatable { return(!x.Equals(y, PythonContext.GetContext(context).EqualityComparerNonGeneric)); }
// Structural Equality and Hashing Helpers public static int StructuralHashMethod(CodeContext /*!*/ context, IStructuralEquatable x) { return(x.GetHashCode(PythonContext.GetContext(context).EqualityComparerNonGeneric)); }
public static void PerformModuleReload(PythonContext /*!*/ context, PythonDictionary /*!*/ dict) { context.EnsureModuleException(_ErrorKey, dict, "Error", "binascii"); context.EnsureModuleException(_IncompleteKey, dict, "Incomplete", "binascii"); }
public BuiltinCallable(PythonContext/*!*/ binder, PythonIndexType op, BuiltinFunction/*!*/ func) : base(binder, op) { Assert.NotNull(func); _bf = func; }
public static void warn_explicit(CodeContext context, object message, PythonType category, string filename, int lineno, string module = null, PythonDictionary registry = null, object module_globals = null) { PythonContext pContext = context.LanguageContext; PythonDictionary fields = (PythonDictionary)pContext.GetModuleState(_keyFields); object warnings = pContext.GetWarningsModule(); PythonExceptions.BaseException msg; string text; // message text if (string.IsNullOrEmpty(module)) { module = (filename == null || filename == "") ? "<unknown>" : filename; if (module.EndsWith(".py")) { module = module.Substring(0, module.Length - 3); } } if (registry == null) { registry = new PythonDictionary(); } if (PythonOps.IsInstance(message, PythonExceptions.Warning)) { msg = (PythonExceptions.BaseException)message; text = msg.ToString(); category = DynamicHelpers.GetPythonType(msg); } else { text = message.ToString(); msg = PythonExceptions.CreatePythonThrowable(category, message.ToString()); } PythonTuple key = PythonTuple.MakeTuple(text, category, lineno); if (registry.ContainsKey(key)) { return; } string action = Converter.ConvertToString(fields[_keyDefaultAction]); PythonTuple last_filter = null; bool loop_break = false; PythonList filters = (PythonList)fields[_keyFilters]; if (warnings != null) { filters = PythonOps.GetBoundAttr(context, warnings, "filters") as PythonList; if (filters == null) { throw PythonOps.ValueError("_warnings.filters must be a list"); } } foreach (PythonTuple filter in filters) { last_filter = filter; action = (string)filter._data[0]; PythonRegex.RE_Pattern fMsg = (PythonRegex.RE_Pattern)filter._data[1]; PythonType fCat = (PythonType)filter._data[2]; PythonRegex.RE_Pattern fMod = (PythonRegex.RE_Pattern)filter._data[3]; int fLno; if (filter._data[4] is int) { fLno = (int)filter._data[4]; } else { fLno = (Extensible <int>)filter._data[4]; } if ((fMsg == null || fMsg.match(text) != null) && category.IsSubclassOf(fCat) && (fMod == null || fMod.match(module) != null) && (fLno == 0 || fLno == lineno)) { loop_break = true; break; } } if (!loop_break) { action = Converter.ConvertToString(fields[_keyDefaultAction]); } switch (action) { case "ignore": registry.Add(key, 1); return; case "error": throw msg.GetClrException(); case "once": registry.Add(key, 1); PythonTuple onceKey = PythonTuple.MakeTuple(text, category); PythonDictionary once_reg = (PythonDictionary)fields[_keyOnceRegistry]; if (once_reg.ContainsKey(onceKey)) { return; } once_reg.Add(key, 1); break; case "always": break; case "module": registry.Add(key, 1); PythonTuple altKey = PythonTuple.MakeTuple(text, category, 0); if (registry.ContainsKey(altKey)) { return; } registry.Add(altKey, 1); break; case "default": registry.Add(key, 1); break; default: throw PythonOps.RuntimeError("Unrecognized action ({0}) in warnings.filters:\n {1}", action, last_filter); } if (warnings != null) { object show_fxn = PythonOps.GetBoundAttr(context, warnings, "showwarning"); if (show_fxn != null) { PythonCalls.Call( context, show_fxn, msg, category, filename, lineno, null, null); } else { showwarning(context, msg, category, filename, lineno, null, null); } } else { showwarning(context, msg, category, filename, lineno, null, null); } }
public abstract DynamicMetaObject/*!*/ MakeRule(DynamicMetaObjectBinder/*!*/ metaBinder, PythonContext/*!*/ binder, DynamicMetaObject/*!*/[]/*!*/ args);
public override DynamicMetaObject /*!*/ BindInvoke(InvokeBinder /*!*/ call, params DynamicMetaObject /*!*/[] /*!*/ args) { return(MakeCallRule(call, AstUtils.Constant(PythonContext.GetPythonContext(call).SharedContext), args)); }
private static DynamicMetaObject/*!*/ GetGetOrDeleteSlice(PythonContext state, DynamicMetaObject/*!*/[]/*!*/ args) { DynamicMetaObject[] newArgs = (DynamicMetaObject[])args.Clone(); for (int i = 1; i < newArgs.Length; i++) { if (!IsIndexType(state, newArgs[i])) { newArgs[i] = newArgs[i].Restrict(newArgs[i].GetLimitType()); } } return new DynamicMetaObject( Ast.Call( typeof(PythonOps).GetMethod("MakeSlice"), AstUtils.Convert(GetGetOrDeleteParameter(newArgs, 1), typeof(object)), AstUtils.Convert(GetGetOrDeleteParameter(newArgs, 2), typeof(object)), AstUtils.Convert(GetGetOrDeleteParameter(newArgs, 3), typeof(object)) ), BindingRestrictions.Combine(newArgs) ); }
private DynamicMetaObject /*!*/ MakeGetMember(DynamicMetaObjectBinder /*!*/ member, DynamicMetaObject codeContext) { PerfTrack.NoteEvent(PerfTrack.Categories.Binding, "OldClass GetMember"); PerfTrack.NoteEvent(PerfTrack.Categories.BindingTarget, "OldClass GetMember"); DynamicMetaObject self = Restrict(typeof(OldClass)); Expression target; string memberName = GetGetMemberName(member); switch (memberName) { case "__dict__": target = Ast.Block( Ast.Call( typeof(PythonOps).GetMethod("OldClassDictionaryIsPublic"), self.Expression ), Ast.Call( typeof(PythonOps).GetMethod("OldClassGetDictionary"), self.Expression ) ); break; case "__bases__": target = Ast.Call( typeof(PythonOps).GetMethod("OldClassGetBaseClasses"), self.Expression ); break; case "__name__": target = Ast.Call( typeof(PythonOps).GetMethod("OldClassGetName"), self.Expression ); break; default: ParameterExpression tmp = Ast.Variable(typeof(object), "lookupVal"); return(new DynamicMetaObject( Ast.Block( new ParameterExpression[] { tmp }, Ast.Condition( Expression.Not( Expression.TypeIs( Expression.Assign( tmp, Ast.Call( typeof(PythonOps).GetMethod("OldClassTryLookupValue"), AstUtils.Constant(PythonContext.GetPythonContext(member).SharedContext), self.Expression, AstUtils.Constant(memberName) ) ), typeof(OperationFailed) ) ), tmp, AstUtils.Convert( GetMemberFallback(this, member, codeContext).Expression, typeof(object) ) ) ), self.Restrictions )); } return(new DynamicMetaObject( target, self.Restrictions )); }
private static bool MakeOneTarget(PythonContext/*!*/ 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, typeof(object)); return false; } }
/// <summary> /// Creates a new InvokeBinder which will call with positional splatting. /// /// The signature of the target site should be object(function), object[], retType /// </summary> /// <param name="state"></param> /// <returns></returns> public static PythonInvokeBinder /*!*/ InvokeSplat(PythonContext /*!*/ state) { return(state.Invoke( new CallSignature(new Argument(ArgumentType.List)) )); }
/// <summary> /// Creates a new InvokeBinder which will call with positional splatting. /// /// The signature of the target site should be object(function), object[], retType /// </summary> /// <param name="state"></param> /// <returns></returns> public static PythonInvokeBinder/*!*/ InvokeSplat(PythonContext/*!*/ state) { return state.Invoke( new CallSignature(new Argument(ArgumentType.List)) ); }
public override DynamicMetaObject /*!*/ BindCreateInstance(CreateInstanceBinder /*!*/ create, params DynamicMetaObject /*!*/[] /*!*/ args) { return(MakeCallRule(create, AstUtils.Constant(PythonContext.GetPythonContext(create).SharedContext), args)); }
public static void warn(CodeContext context, object message, PythonType category = null, int stacklevel = 1) { PythonContext pContext = context.LanguageContext; PythonList argv = pContext.GetSystemStateValue("argv") as PythonList; if (PythonOps.IsInstance(message, PythonExceptions.Warning)) { category = DynamicHelpers.GetPythonType(message); } if (category == null) { category = PythonExceptions.UserWarning; } if (!category.IsSubclassOf(PythonExceptions.Warning)) { throw PythonOps.ValueError("category is not a subclass of Warning"); } TraceBackFrame caller = null; PythonDictionary globals; int lineno; if (context.LanguageContext.PythonOptions.Frames) { try { caller = SysModule._getframeImpl(context, stacklevel - 1); } catch (ValueErrorException) { } } if (caller == null) { globals = Builtin.globals(context) as PythonDictionary; lineno = 1; } else { globals = caller.f_globals; lineno = (int)caller.f_lineno; } string module; string filename; if (globals != null && globals.ContainsKey("__name__")) { module = (string)globals.get("__name__"); } else { module = "<string>"; } filename = globals.get("__file__") as string; if (filename == null || filename == "") { if (module == "__main__") { if (argv != null && argv.Count > 0) { filename = argv[0] as string; } else { // interpreter lacks sys.argv filename = "__main__"; } } if (filename == null || filename == "") { filename = module; } } PythonDictionary registry = (PythonDictionary)globals.setdefault("__warningregistry__", new PythonDictionary()); warn_explicit(context, message, category, filename, lineno, module, registry, globals); }
public override DynamicMetaObject /*!*/ BindInvoke(InvokeBinder /*!*/ call, params DynamicMetaObject /*!*/[] /*!*/ args) { // TODO: Context should come from BuiltinFunction return(InvokeWorker(call, PythonContext.GetCodeContext(call), args)); }
private static void LoadScriptCode(PythonContext/*!*/ pc, Assembly/*!*/ asm) { ScriptCode[] codes = ScriptCode.LoadFromAssembly(pc.DomainManager, asm); foreach (ScriptCode sc in codes) { pc.GetCompiledLoader().AddScriptCode(sc); } }
public MmapDefault(CodeContext /*!*/ context, int fileno, long length, string tagname = null, int access = ACCESS_WRITE, long offset = 0) { switch (access) { case ACCESS_READ: _fileAccess = MemoryMappedFileAccess.Read; break; case ACCESS_WRITE: _fileAccess = MemoryMappedFileAccess.ReadWrite; break; case ACCESS_COPY: _fileAccess = MemoryMappedFileAccess.CopyOnWrite; break; default: throw PythonOps.ValueError("mmap invalid access parameter"); } if (length < 0) { throw PythonOps.OverflowError("memory mapped size must be positive"); } if (offset < 0) { throw PythonOps.OverflowError("memory mapped offset must be positive"); } if (IntPtr.Size == 4 && length > int.MaxValue) { throw PythonOps.OverflowError("cannot fit 'long' into an index-sized integer"); } // CPython only allows offsets that are a multiple of ALLOCATIONGRANULARITY if (offset % ALLOCATIONGRANULARITY != 0) { throw WindowsError(PythonExceptions._WindowsError.ERROR_MAPPED_ALIGNMENT); } // .NET throws on an empty tagname, but CPython treats it as null. _mapName = tagname == "" ? null : tagname; if (fileno == -1 || fileno == 0) { // Map anonymous memory that is not tied to a file. // Note: CPython seems to allow 0 as a file descriptor even though it represents stdin. _offset = 0; // offset is ignored without an underlying file _sourceStream = null; // work around the .NET bug whereby CreateOrOpen throws on a null mapName if (_mapName is null) { _file = MemoryMappedFile.CreateNew(null, length, _fileAccess); } else { Debug.Assert(RuntimeInformation.IsOSPlatform(OSPlatform.Windows)); _file = MemoryMappedFile.CreateOrOpen(_mapName, length, _fileAccess); } } else { // Memory-map an actual file _offset = offset; PythonContext pContext = context.LanguageContext; if (pContext.FileManager.TryGetFileFromId(pContext, fileno, out PythonFile file)) { if ((_sourceStream = file._stream as FileStream) == null) { throw WindowsError(PythonExceptions._WindowsError.ERROR_INVALID_HANDLE); } } else if (pContext.FileManager.TryGetObjectFromId(pContext, fileno, out object obj) && obj is PythonIOModule.FileIO fileio) { if ((_sourceStream = fileio._readStream as FileStream) == null) { throw WindowsError(PythonExceptions._WindowsError.ERROR_INVALID_HANDLE); } } else { throw Error(context, PythonExceptions._WindowsError.ERROR_INVALID_BLOCK, "Bad file descriptor"); } if (_fileAccess == MemoryMappedFileAccess.ReadWrite && !_sourceStream.CanWrite) { throw WindowsError(PythonExceptions._WindowsError.ERROR_ACCESS_DENIED); } if (length == 0) { length = _sourceStream.Length; if (length == 0) { throw PythonOps.ValueError("cannot mmap an empty file"); } if (_offset >= length) { throw PythonOps.ValueError("mmap offset is greater than file size"); } length -= _offset; } long capacity = checked (_offset + length); // Enlarge the file as needed. if (capacity > _sourceStream.Length) { if (_sourceStream.CanWrite) { _sourceStream.SetLength(capacity); } else { throw WindowsError(PythonExceptions._WindowsError.ERROR_NOT_ENOUGH_MEMORY); } } _file = CreateFromFile( _sourceStream, _mapName, _sourceStream.Length, _fileAccess, HandleInheritability.None, true); } try { _view = _file.CreateViewAccessor(_offset, length, _fileAccess); } catch { _file.Dispose(); _file = null; throw; } _position = 0L; }
/// <summary> /// Creates a new InvokeBinder which will call with positional and keyword splatting. /// /// The signature of the target site should be object(function), object[], dictionary, retType /// </summary> public static PythonInvokeBinder/*!*/ InvokeKeywords(PythonContext/*!*/ state) { return state.Invoke( new CallSignature(new Argument(ArgumentType.List), new Argument(ArgumentType.Dictionary)) ); }
private static void DoCoerce(PythonContext/*!*/ state, ConditionalBuilder/*!*/ bodyBuilder, PythonOperationKind op, DynamicMetaObject/*!*/[]/*!*/ types, bool reverse) { DoCoerce(state, bodyBuilder, op, types, reverse, delegate(Expression e) { return e; }); }
public static void PerformModuleReload(PythonContext /*!*/ context, PythonDictionary /*!*/ dict) { context.EnsureModuleException(_mmapErrorKey, PythonExceptions.EnvironmentError, dict, "error", "mmap"); }
/// <summary> /// Creates a new InvokeBinder which will call with positional and keyword splatting. /// /// The signature of the target site should be object(function), object[], dictionary, retType /// </summary> public static PythonInvokeBinder /*!*/ InvokeKeywords(PythonContext /*!*/ state) { return(state.Invoke( new CallSignature(new Argument(ArgumentType.List), new Argument(ArgumentType.Dictionary)) )); }
private static void MakeSlotCallWorker(PythonContext/*!*/ 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.SharedContext), 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, DynamicExpression.Dynamic( state.Invoke( new CallSignature(args.Length) ), typeof(object), ArrayUtils.Insert(AstUtils.Constant(state.SharedContext), (Expression)callable, args) ) ), Ast.Property(null, typeof(PythonOps).GetProperty("NotImplemented")) ) ), tmp ); bodyBuilder.AddVariable(callable); bodyBuilder.AddVariable(tmp); }
private void MakeReverseDelegateWorker(CodeContext context) { Type[] sigTypes; Type[] callSiteType; Type retType; GetSignatureInfo(out sigTypes, out callSiteType, out retType); DynamicMethod dm = new DynamicMethod("ReverseInteropInvoker", retType, ArrayUtils.RemoveLast(sigTypes), DynamicModule); ILGenerator ilGen = dm.GetILGenerator(); PythonContext pc = context.LanguageContext; Type callDelegateSiteType = CompilerHelpers.MakeCallSiteDelegateType(callSiteType); CallSite site = CallSite.Create(callDelegateSiteType, pc.Invoke(new CallSignature(_argtypes.Length))); List <object> constantPool = new List <object>(); constantPool.Add(null); // 1st item is the target object, will be put in later. constantPool.Add(site); ilGen.BeginExceptionBlock(); //CallSite<Func<CallSite, object, object>> mySite; //mySite.Target(mySite, target, ...); LocalBuilder siteLocal = ilGen.DeclareLocal(site.GetType()); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldc_I4, constantPool.Count - 1); ilGen.Emit(OpCodes.Ldelem_Ref); ilGen.Emit(OpCodes.Castclass, site.GetType()); ilGen.Emit(OpCodes.Stloc, siteLocal); ilGen.Emit(OpCodes.Ldloc, siteLocal); ilGen.Emit(OpCodes.Ldfld, site.GetType().GetField("Target")); ilGen.Emit(OpCodes.Ldloc, siteLocal); // load code context int contextIndex = constantPool.Count; Debug.Assert(pc.SharedContext != null); constantPool.Add(pc.SharedContext); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldc_I4, contextIndex); ilGen.Emit(OpCodes.Ldelem_Ref); // load function target, in constant pool slot 0 ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldc_I4_0); ilGen.Emit(OpCodes.Ldelem_Ref); // load arguments for (int i = 0; i < _argtypes.Length; i++) { INativeType nativeType = _argtypes[i]; nativeType.EmitReverseMarshalling(ilGen, new Arg(i + 1, sigTypes[i + 1]), constantPool, 0); } ilGen.Emit(OpCodes.Call, callDelegateSiteType.GetMethod("Invoke")); LocalBuilder finalRes = null; // emit forward marshaling for return value if (_restype != null) { LocalBuilder tmpRes = ilGen.DeclareLocal(typeof(object)); ilGen.Emit(OpCodes.Stloc, tmpRes); finalRes = ilGen.DeclareLocal(retType); ((INativeType)_restype).EmitMarshalling(ilGen, new Local(tmpRes), constantPool, 0); ilGen.Emit(OpCodes.Stloc, finalRes); } else { ilGen.Emit(OpCodes.Pop); } // } catch(Exception e) { // emit the cleanup code ilGen.BeginCatchBlock(typeof(Exception)); ilGen.Emit(OpCodes.Ldarg_0); ilGen.Emit(OpCodes.Ldc_I4, contextIndex); ilGen.Emit(OpCodes.Ldelem_Ref); ilGen.Emit(OpCodes.Call, typeof(ModuleOps).GetMethod("CallbackException")); ilGen.EndExceptionBlock(); if (_restype != null) { ilGen.Emit(OpCodes.Ldloc, finalRes); } ilGen.Emit(OpCodes.Ret); _reverseDelegateConstants = constantPool; _reverseDelegateType = GetReverseDelegateType(ArrayUtils.RemoveFirst(sigTypes), CallingConvention); _reverseDelegate = dm; }
/// <summary> /// calls __coerce__ for old-style classes and performs the operation if the coercion is successful. /// </summary> private static void DoCoerce(PythonContext/*!*/ pyContext, ConditionalBuilder/*!*/ bodyBuilder, PythonOperationKind op, DynamicMetaObject/*!*/[]/*!*/ types, bool reverse, Func<Expression, Expression> returnTransform) { ParameterExpression coerceResult = Ast.Variable(typeof(object), "coerceResult"); ParameterExpression coerceTuple = Ast.Variable(typeof(PythonTuple), "coerceTuple"); // tmp = self.__coerce__(other) // if tmp != null && tmp != NotImplemented && (tuple = PythonOps.ValidateCoerceResult(tmp)) != null: // return operation(tuple[0], tuple[1]) SlotOrFunction slot = SlotOrFunction.GetSlotOrFunction(pyContext, "__coerce__", types); if (slot.Success) { bodyBuilder.AddCondition( Ast.AndAlso( Ast.Not( Ast.TypeIs( Ast.Assign( coerceResult, slot.Target.Expression ), typeof(OldInstance) ) ), Ast.NotEqual( Ast.Assign( coerceTuple, Ast.Call( typeof(PythonOps).GetMethod("ValidateCoerceResult"), coerceResult ) ), AstUtils.Constant(null) ) ), BindingHelpers.AddRecursionCheck( pyContext, returnTransform( DynamicExpression.Dynamic( pyContext.Operation(op | PythonOperationKind.DisableCoerce), op == PythonOperationKind.Compare ? typeof(int) : typeof(object), reverse ? CoerceTwo(coerceTuple) : CoerceOne(coerceTuple), reverse ? CoerceOne(coerceTuple) : CoerceTwo(coerceTuple) ) ) ) ); bodyBuilder.AddVariable(coerceResult); bodyBuilder.AddVariable(coerceTuple); } }
public TResult MakeTypeGetMember() { PythonTypeSlot pts; bool isFinal = false, metaOnly = false; CodeContext lookupContext = PythonContext.GetContext(_context).SharedClsContext; // first look in the meta-class to see if we have a get/set descriptor PythonType metaType = DynamicHelpers.GetPythonType(Value); foreach (PythonType pt in metaType.ResolutionOrder) { if (pt.TryLookupSlot(lookupContext, _name, out pts) && pts.IsSetDescriptor(lookupContext, metaType)) { if (AddMetaSlotAccess(metaType, pts)) { metaOnly = isFinal = true; break; } } } if (!isFinal) { // then search the MRO to see if we have the value foreach (PythonType pt in Value.ResolutionOrder) { if (pt.IsOldClass) { // mixed new-style/old-style class, search the one slot in it's MRO for the member AddOldClassAccess(pt); } else if (pt.TryLookupSlot(lookupContext, _name, out pts)) { if (AddSlotAccess(pt, pts)) { isFinal = true; break; } } } } if (!isFinal) { // then go back to the meta class to see if we have a normal attribute foreach (PythonType pt in metaType.ResolutionOrder) { if (pt.OldClass != null) { // mixed new-style/old-style class, just call our version of __getattribute__ // and let it sort it out at runtime. AddMetaOldClassAccess(); isFinal = true; break; } else if (pt.TryLookupSlot(lookupContext, _name, out pts)) { if (AddMetaSlotAccess(metaType, pts)) { isFinal = true; break; } } } } if (!isFinal) { // the member doesn't exist anywhere in the type hierarchy, see if // we define __getattr__ on our meta type. if (metaType.TryResolveSlot(_context, "__getattr__", out pts) && !pts.IsSetDescriptor(lookupContext, metaType)) // we tried get/set descriptors initially { AddMetaGetAttribute(metaType, pts); isFinal = pts.GetAlwaysSucceeds; } } if (!isFinal) { AddError(); } return(Finish(metaOnly)); }
/// <summary> /// Gets the arguments that need to be provided to __*item__ when we need to pass a slice object. /// </summary> private static DynamicMetaObject/*!*/[]/*!*/ GetItemSliceArguments(PythonContext state, PythonIndexType op, DynamicMetaObject/*!*/[]/*!*/ types) { DynamicMetaObject[] args; if (op == PythonIndexType.SetSlice) { args = new DynamicMetaObject[] { types[0].Restrict(types[0].GetLimitType()), GetSetSlice(state, types), types[types.Length- 1].Restrict(types[types.Length - 1].GetLimitType()) }; } else { Debug.Assert(op == PythonIndexType.GetSlice || op == PythonIndexType.DeleteSlice); args = new DynamicMetaObject[] { types[0].Restrict(types[0].GetLimitType()), GetGetOrDeleteSlice(state, types) }; } return args; }
public override DynamicMetaObject /*!*/ BindGetMember(GetMemberBinder /*!*/ member) { return(GetMemberWorker(member, PythonContext.GetCodeContext(member))); }
/// <summary> /// Creates a new CallableObject. If BuiltinFunction is available we'll create a BuiltinCallable otherwise /// we create a SlotCallable. /// </summary> public static Callable MakeCallable(PythonContext/*!*/ binder, PythonIndexType op, BuiltinFunction itemFunc, PythonTypeSlot itemSlot) { if (itemFunc != null) { // we'll call a builtin function to produce the rule return new BuiltinCallable(binder, op, itemFunc); } else if (itemSlot != null) { // we'll call a PythonTypeSlot to produce the rule return new SlotCallable(binder, op, itemSlot); } return null; }
public MetaGetAttributeDelegate(CodeContext context, PythonTypeSlot slot, PythonType metaType, string name) { _name = name; if (metaType.IsSystemType) { _metaType = metaType; _slot = slot; } else { _weakMetaType = metaType.GetSharedWeakReference(); _weakSlot = new WeakReference(slot); } _invokeSite = CallSite <Func <CallSite, CodeContext, object, string, object> > .Create(PythonContext.GetContext(context).InvokeOne); }
public SlotCallable(PythonContext/*!*/ binder, PythonIndexType op, PythonTypeSlot slot) : base(binder, op) { _slot = slot; }
private DynamicMetaObject /*!*/ MakeSetMember(SetMemberBinder /*!*/ member, DynamicMetaObject /*!*/ value) { PythonContext state = PythonContext.GetPythonContext(member); DynamicMetaObject self = Restrict(Value.GetType()); if (Value.GetType() != typeof(PythonType) && DynamicHelpers.GetPythonType(Value).IsSystemType) { // built-in subclass of .NET type. Usually __setattr__ is handled by MetaUserObject // but we can have a built-in subtype that's not a user type. PythonTypeSlot pts; if (Value.TryGetCustomSetAttr(state.SharedContext, out pts)) { Debug.Assert(pts.GetAlwaysSucceeds); ParameterExpression tmp = Ast.Variable(typeof(object), "boundVal"); return(BindingHelpers.AddDynamicTestAndDefer( member, new DynamicMetaObject( Ast.Block( new[] { tmp }, Ast.Dynamic( state.Invoke(new CallSignature(2)), typeof(object), AstUtils.Constant(state.SharedContext), Ast.Block( Ast.Call( typeof(PythonOps).GetMethod("SlotTryGetValue"), AstUtils.Constant(state.SharedContext), AstUtils.Convert(AstUtils.WeakConstant(pts), typeof(PythonTypeSlot)), AstUtils.Convert(Expression, typeof(object)), AstUtils.Convert(AstUtils.WeakConstant(DynamicHelpers.GetPythonType(Value)), typeof(PythonType)), tmp ), tmp ), Ast.Constant(member.Name), value.Expression ) ), self.Restrictions ), new DynamicMetaObject[] { this, value }, TestUserType() )); } } return(BindingHelpers.AddDynamicTestAndDefer( member, new DynamicMetaObject( Ast.Call( typeof(PythonOps).GetMethod("PythonTypeSetCustomMember"), AstUtils.Constant(PythonContext.GetPythonContext(member).SharedContext), self.Expression, AstUtils.Constant(member.Name), AstUtils.Convert( value.Expression, typeof(object) ) ), self.Restrictions.Merge(value.Restrictions) ), new DynamicMetaObject[] { this, value }, TestUserType() )); }
public override DynamicMetaObject/*!*/ MakeRule(DynamicMetaObjectBinder/*!*/ metaBinder, PythonContext/*!*/ binder, DynamicMetaObject/*!*/[]/*!*/ args) { // the semantics of simple slicing state that if the value // is less than 0 then the length is added to it. The default // for unprovided parameters are 0 and maxint. The callee // is responsible for ignoring out of range values but slicing // is responsible for doing this initial transformation. Debug.Assert(args.Length > 2); // index 1 and 2 should be our slice indexes, we might have another arg if we're a setter args = ArrayUtils.Copy(args); for (int i = 1; i < 3; i++) { args[i] = args[i].Restrict(args[i].GetLimitType()); if (args[i].GetLimitType() == typeof(MissingParameter)) { switch (i) { case 1: args[i] = new DynamicMetaObject(AstUtils.Constant(0), args[i].Restrictions); break; case 2: args[i] = new DynamicMetaObject(AstUtils.Constant(Int32.MaxValue), args[i].Restrictions); break; } } else if (args[i].GetLimitType() == typeof(int)) { args[i] = MakeIntTest(args[0], args[i]); } else if (args[i].GetLimitType().IsSubclassOf(typeof(Extensible<int>))) { args[i] = MakeIntTest( args[0], new DynamicMetaObject( Ast.Property( args[i].Expression, args[i].GetLimitType().GetProperty("Value") ), args[i].Restrictions ) ); } else if (args[i].GetLimitType() == typeof(BigInteger)) { args[i] = MakeBigIntTest(args[0], args[i]); } else if (args[i].GetLimitType().IsSubclassOf(typeof(Extensible<BigInteger>))) { args[i] = MakeBigIntTest(args[0], new DynamicMetaObject(Ast.Property(args[i].Expression, args[i].GetLimitType().GetProperty("Value")), args[i].Restrictions)); } else if (args[i].GetLimitType() == typeof(bool)) { args[i] = new DynamicMetaObject( Ast.Condition(args[i].Expression, AstUtils.Constant(1), AstUtils.Constant(0)), args[i].Restrictions ); } else { // this type defines __index__, otherwise we'd have an ItemBuilder constructing a slice args[i] = MakeIntTest(args[0], new DynamicMetaObject( DynamicExpression.Dynamic( binder.Convert( typeof(int), ConversionResultKind.ExplicitCast ), typeof(int), DynamicExpression.Dynamic( binder.InvokeNone, typeof(object), AstUtils.Constant(binder.SharedContext), Binders.Get( AstUtils.Constant(binder.SharedContext), binder, typeof(object), "__index__", Ast.Convert( args[i].Expression, typeof(object) ) ) ) ), args[i].Restrictions ) ); } } if (_lengthVar != null) { // we need the length which we should only calculate once, calculate and // store it in a temporary. Note we only calculate the length if we'll DynamicMetaObject res = Callable.CompleteRuleTarget(metaBinder, args, null); return new DynamicMetaObject( Ast.Block( new ParameterExpression[] { _lengthVar }, Ast.Assign(_lengthVar, AstUtils.Constant(null, _lengthVar.Type)), res.Expression ), res.Restrictions ); } return Callable.CompleteRuleTarget(metaBinder, args, null); }
protected override void Initialize() { Debug.Assert(Language != null); base.Initialize(); Console.Output = new OutputWriter(PythonContext, false); Console.ErrorOutput = new OutputWriter(PythonContext, true); // TODO: must precede path initialization! (??? - test test_importpkg.py) int pathIndex = PythonContext.PythonOptions.SearchPaths.Count; Language.DomainManager.LoadAssembly(typeof(string).Assembly); Language.DomainManager.LoadAssembly(typeof(System.Diagnostics.Debug).Assembly); InitializePath(ref pathIndex); InitializeModules(); InitializeExtensionDLLs(); ImportSite(); // Equivalent to -i command line option // Check if IRONPYTHONINSPECT was set before execution string inspectLine = Environment.GetEnvironmentVariable("IRONPYTHONINSPECT"); if (inspectLine != null) { Options.Introspection = true; } // If running in console mode (including with -c), the current working directory should be // the first entry in sys.path. If running a script file, however, the CWD should not be added; // instead, the script's containg folder should be added. string fullPath = "."; // this is a valid path resolving to current working dir. Pinky-swear. if (Options.Command == null && Options.FileName != null) { if (Options.FileName == "-") { Options.FileName = "<stdin>"; } else { #if !SILVERLIGHT if (Directory.Exists(Options.FileName)) { Options.FileName = Path.Combine(Options.FileName, "__main__.py"); } if (!File.Exists(Options.FileName)) { Console.WriteLine( String.Format( System.Globalization.CultureInfo.InvariantCulture, "File {0} does not exist.", Options.FileName), Style.Error); Environment.Exit(1); } #endif fullPath = Path.GetDirectoryName( Language.DomainManager.Platform.GetFullPath(Options.FileName) ); } } PythonContext.InsertIntoPath(0, fullPath); PythonContext.MainThread = Thread.CurrentThread; }
private static bool IsIndexType(PythonContext/*!*/ state, DynamicMetaObject/*!*/ obj) { bool numeric = true; if (obj.GetLimitType() != typeof(MissingParameter) && !PythonOps.IsNumericType(obj.GetLimitType())) { PythonType curType = MetaPythonObject.GetPythonType(obj); PythonTypeSlot dummy; if (!curType.TryResolveSlot(state.SharedContext, "__index__", out dummy)) { numeric = false; } } return numeric; }
/// <summary> /// Returns the display look for IronPython. /// /// The returned string uses This \n instead of Environment.NewLine for it's line seperator /// because it is intended to be outputted through the Python I/O system. /// </summary> public static string GetLogoDisplay() { return(PythonContext.GetVersionString() + "\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n"); }
/// <summary> /// Checks if a coercion check should be performed. We perform coercion under the following /// situations: /// 1. Old instances performing a binary operator (excluding rich comparisons) /// 2. User-defined new instances calling __cmp__ but only if we wouldn't dispatch to a built-in __coerce__ on the parent type /// /// This matches the behavior of CPython. /// </summary> /// <returns></returns> private static bool ShouldCoerce(PythonContext/*!*/ state, PythonOperationKind operation, DynamicMetaObject/*!*/ x, DynamicMetaObject/*!*/ y, bool isCompare) { if ((operation & PythonOperationKind.DisableCoerce) != 0) { return false; } PythonType xType = MetaPythonObject.GetPythonType(x), yType = MetaPythonObject.GetPythonType(y); if (xType == TypeCache.OldInstance) return true; if (isCompare && !xType.IsSystemType && yType.IsSystemType) { if (yType == TypeCache.Int32 || yType == TypeCache.BigInteger || yType == TypeCache.Double || yType == TypeCache.Complex) { // only coerce new style types that define __coerce__ and // only when comparing against built-in types which // define __coerce__ PythonTypeSlot pts; if (xType.TryResolveSlot(state.SharedContext, "__coerce__", out pts)) { // don't call __coerce__ if it's declared on the base type BuiltinMethodDescriptor bmd = pts as BuiltinMethodDescriptor; if (bmd == null) return true; if (bmd.__name__ != "__coerce__" && bmd.DeclaringType != typeof(int) && bmd.DeclaringType != typeof(BigInteger) && bmd.DeclaringType != typeof(double) && bmd.DeclaringType != typeof(Complex)) { return true; } foreach (PythonType pt in xType.ResolutionOrder) { if (pt.UnderlyingSystemType == bmd.DeclaringType) { // inherited __coerce__ return false; } } return true; } } } return false; }
SourceUnit CreateSourceUnit(PythonContext context, string expression) { StringTextContentProvider textProvider = new StringTextContentProvider(expression); return(context.CreateSourceUnit(textProvider, String.Empty, SourceCodeKind.SingleStatement)); }
private static void GetOperatorMethods(DynamicMetaObject/*!*/[]/*!*/ types, PythonOperationKind oper, PythonContext state, out SlotOrFunction fbinder, out SlotOrFunction rbinder, out PythonTypeSlot fSlot, out PythonTypeSlot rSlot) { oper = NormalizeOperator(oper); oper &= ~PythonOperationKind.InPlace; string 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, null, out fbinder, out fParent)) { foreach (PythonType pt in MetaPythonObject.GetPythonType(types[0]).ResolutionOrder) { if (pt.TryLookupSlot(state.SharedContext, op, out fSlot)) { fParent = pt; break; } } } if (!SlotOrFunction.TryGetBinder(state, types, null, rop, out rbinder, out rParent)) { foreach (PythonType pt in MetaPythonObject.GetPythonType(types[1]).ResolutionOrder) { if (pt.TryLookupSlot(state.SharedContext, 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 == "__truediv__" || op == "__rtruediv__") { // true div on a type which doesn't support it, go ahead and try normal divide PythonOperationKind newOp = op == "__truediv__" ? PythonOperationKind.Divide : PythonOperationKind.ReverseDivide; GetOperatorMethods(types, newOp, state, out fbinder, out rbinder, out fSlot, out rSlot); } } }
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("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("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) )); } }
private static void MakeSlotCall(PythonContext/*!*/ 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); }
internal static DynamicMetaObject TranslateArguments(DynamicMetaObjectBinder call, Expression codeContext, DynamicMetaObject function, DynamicMetaObject /*!*/[] args, bool hasSelf, string name) { if (hasSelf) { args = ArrayUtils.RemoveFirst(args); } CallSignature sig = BindingHelpers.GetCallSignature(call); if (sig.HasDictionaryArgument()) { int index = sig.IndexOf(ArgumentType.Dictionary); DynamicMetaObject dict = args[index]; if (!(dict.Value is IDictionary) && dict.Value != null) { // The DefaultBinder only handles types that implement IDictionary. Here we have an // arbitrary user-defined mapping type. We'll convert it into a PythonDictionary // and then have an embedded dynamic site pass that dictionary through to the default // binder. DynamicMetaObject[] dynamicArgs = ArrayUtils.Insert(function, args); dynamicArgs[index + 1] = new DynamicMetaObject( Expression.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.UserMappingToPythonDictionary)), codeContext, args[index].Expression, AstUtils.Constant(name) ), BindingRestrictionsHelpers.GetRuntimeTypeRestriction(dict.Expression, dict.GetLimitType()), PythonOps.UserMappingToPythonDictionary(PythonContext.GetPythonContext(call).SharedContext, dict.Value, name) ); if (call is IPythonSite) { dynamicArgs = ArrayUtils.Insert( new DynamicMetaObject(codeContext, BindingRestrictions.Empty), dynamicArgs ); } return(new DynamicMetaObject( DynamicExpression.Dynamic( call, typeof(object), DynamicUtils.GetExpressions(dynamicArgs) ), BindingRestrictions.Combine(dynamicArgs).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(dict.Expression, dict.GetLimitType())) )); } } if (sig.HasListArgument()) { int index = sig.IndexOf(ArgumentType.List); DynamicMetaObject list = args[index]; if (!(list.Value is IList <object>) && list.Value != null) { // The DefaultBinder only handles types that implement IList<object>. Here we have a // arbitrary user-defined sequence type. We'll convert it into a tuple and then have // an embedded dynamic site pass that tuple through to the default binder. DynamicMetaObject[] dynamicArgs = ArrayUtils.Insert(function, args); dynamicArgs[index + 1] = new DynamicMetaObject( Expression.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.UserMappingToPythonTuple)), codeContext, args[index].Expression, AstUtils.Constant(name) ), BindingRestrictions.Empty ); if (call is IPythonSite) { dynamicArgs = ArrayUtils.Insert( new DynamicMetaObject(codeContext, BindingRestrictions.Empty), dynamicArgs ); } return(new DynamicMetaObject( DynamicExpression.Dynamic( call, typeof(object), DynamicUtils.GetExpressions(dynamicArgs) ), function.Restrictions.Merge( BindingRestrictions.Combine(args).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(list.Expression, list.GetLimitType())) ) )); } } return(null); }