示例#1
0
 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)
                ));
 }
示例#2
0
        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);
        }
示例#3
0
            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);
        }
示例#5
0
 /// <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))
     );
 }
示例#6
0
 /// <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))
     );
 }
示例#7
0
            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;
            }
示例#8
0
 /// <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))
                ));
 }
示例#9
0
 /// <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))
                ));
 }
示例#10
0
        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()
                       ));
        }
示例#12
0
 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)
     );
 }