public static Expression /*!*/ Invoke(Expression codeContext, PythonContext /*!*/ binder, Type /*!*/ resultType, CallSignature signature, params Expression /*!*/[] /*!*/ args) { return(DynamicExpression.Dynamic( binder.Invoke( signature ), resultType, ArrayUtils.Insert(codeContext, args) )); }
public static SlotOrFunction /*!*/ GetSlotOrFunction(PythonContext /*!*/ state, string op, params DynamicMetaObject[] types) { PythonTypeSlot slot; SlotOrFunction res; if (TryGetBinder(state, types, op, null, out res)) { if (res != SlotOrFunction.Empty) { return(res); } } else if (MetaUserObject.GetPythonType(types[0]).TryResolveSlot(state.SharedContext, op, out slot)) { ParameterExpression tmp = Ast.Variable(typeof(object), "slotVal"); Expression[] args = new Expression[types.Length - 1]; for (int i = 1; i < types.Length; i++) { args[i - 1] = types[i].Expression; } return(new SlotOrFunction( new DynamicMetaObject( Ast.Block( new ParameterExpression[] { tmp }, MetaPythonObject.MakeTryGetTypeMember( state, slot, tmp, types[0].Expression, Ast.Call( typeof(DynamicHelpers).GetMethod("GetPythonType"), types[0].Expression ) ), DynamicExpression.Dynamic( state.Invoke( new CallSignature(args.Length) ), typeof(object), ArrayUtils.Insert <Expression>( AstUtils.Constant(state.SharedContext), tmp, args ) ) ), BindingRestrictions.Combine(types).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(types[0].Expression, types[0].GetLimitType())) ), slot )); } return(SlotOrFunction.Empty); }
protected DynamicMetaObject /*!*/ MakeDefaultNew(DefaultBinder /*!*/ binder, Expression /*!*/ function) { // calling theType.__new__(theType, args) List <Expression> args = new List <Expression>(); args.Add(CodeContext); args.Add(function); AppendNewArgs(args); return(new DynamicMetaObject( Ast.Dynamic( PythonContext.Invoke( GetDynamicNewSignature() ), typeof(object), args.ToArray() ), Arguments.Self.Restrictions )); }
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); }
/// <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)) ); }
/// <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)) ); }
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> /// 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)) )); }
/// <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 static SlotOrFunction/*!*/ GetSlotOrFunction(PythonContext/*!*/ state, string op, params DynamicMetaObject[] types) { PythonTypeSlot slot; SlotOrFunction res; if (TryGetBinder(state, types, op, null, out res)) { if (res != SlotOrFunction.Empty) { return res; } } else if (MetaUserObject.GetPythonType(types[0]).TryResolveSlot(state.SharedContext, op, out slot)) { ParameterExpression tmp = Ast.Variable(typeof(object), "slotVal"); Expression[] args = new Expression[types.Length - 1]; for (int i = 1; i < types.Length; i++) { args[i - 1] = types[i].Expression; } return new SlotOrFunction( new DynamicMetaObject( Ast.Block( new ParameterExpression[] { tmp }, MetaPythonObject.MakeTryGetTypeMember( state, slot, tmp, types[0].Expression, Ast.Call( typeof(DynamicHelpers).GetMethod("GetPythonType"), types[0].Expression ) ), Ast.Dynamic( state.Invoke( new CallSignature(args.Length) ), typeof(object), ArrayUtils.Insert<Expression>( AstUtils.Constant(state.SharedContext), tmp, args ) ) ), BindingRestrictions.Combine(types).Merge(BindingRestrictionsHelpers.GetRuntimeTypeRestriction(types[0].Expression, types[0].GetLimitType())) ), slot ); } return SlotOrFunction.Empty; }
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 }, DynamicExpression.Dynamic( state.Invoke(new CallSignature(2)), typeof(object), AstUtils.Constant(state.SharedContext), Ast.Block( Ast.Call( typeof(PythonOps).GetMethod(nameof(PythonOps.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(nameof(PythonOps.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 static Expression/*!*/ Invoke(Expression codeContext, PythonContext/*!*/ binder, Type/*!*/ resultType, CallSignature signature, params Expression/*!*/[]/*!*/ args) { return Ast.Dynamic( binder.Invoke( signature ), resultType, ArrayUtils.Insert(codeContext, args) ); }