Call_3() public static method

public static Call_3 ( IntPtr fp, IntPtr a1, IntPtr a2, IntPtr a3 ) : IntPtr
fp IntPtr
a1 IntPtr
a2 IntPtr
a3 IntPtr
return IntPtr
Exemplo n.º 1
0
        //====================================================================
        // Metatype __call__ implementation. This is needed to ensure correct
        // initialization (__init__ support), because the tp_call we inherit
        // from PyType_Type won't call __init__ for metatypes it doesnt know.
        //====================================================================

        public static IntPtr tp_call(IntPtr tp, IntPtr args, IntPtr kw)
        {
            IntPtr func = Marshal.ReadIntPtr(tp, TypeOffset.tp_new);

            if (func == IntPtr.Zero)
            {
                return(Exceptions.RaiseTypeError("invalid object"));
            }

            IntPtr obj = NativeCall.Call_3(func, tp, args, kw);

            if (obj == IntPtr.Zero)
            {
                return(IntPtr.Zero);
            }

            IntPtr py__init__ = Runtime.PyString_FromString("__init__");
            IntPtr type       = Runtime.PyObject_TYPE(obj);
            IntPtr init       = Runtime._PyType_Lookup(type, py__init__);

            Runtime.Decref(py__init__);
            Runtime.PyErr_Clear();

            if (init != IntPtr.Zero)
            {
                IntPtr bound = Runtime.GetBoundArgTuple(obj, args);
                if (bound == IntPtr.Zero)
                {
                    Runtime.Decref(obj);
                    return(IntPtr.Zero);
                }

                IntPtr result = Runtime.PyObject_Call(init, bound, kw);
                Runtime.Decref(bound);

                if (result == IntPtr.Zero)
                {
                    Runtime.Decref(obj);
                    return(IntPtr.Zero);
                }

                Runtime.Decref(result);
            }

            return(obj);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Metatype __call__ implementation. This is needed to ensure correct
        /// initialization (__init__ support), because the tp_call we inherit
        /// from PyType_Type won't call __init__ for metatypes it doesn't know.
        /// </summary>
        public static IntPtr tp_call(IntPtr tp, IntPtr args, IntPtr kw)
        {
            IntPtr func = Marshal.ReadIntPtr(tp, TypeOffset.tp_new);

            if (func == IntPtr.Zero)
            {
                return(Exceptions.RaiseTypeError("invalid object"));
            }

            IntPtr obj = NativeCall.Call_3(func, tp, args, kw);

            if (obj == IntPtr.Zero)
            {
                return(IntPtr.Zero);
            }

            return(CallInit(obj, args, kw));
        }
Exemplo n.º 3
0
        /// <summary>
        /// Metatype __call__ implementation. This is needed to ensure correct
        /// initialization (__init__ support), because the tp_call we inherit
        /// from PyType_Type won't call __init__ for metatypes it doesn't know.
        /// </summary>
        public static IntPtr tp_call(IntPtr tp, IntPtr args, IntPtr kw)
        {
            IntPtr func = Marshal.ReadIntPtr(tp, TypeOffset.tp_new);

            if (func == IntPtr.Zero)
            {
                return(Exceptions.RaiseTypeError("invalid object"));
            }

            IntPtr obj = NativeCall.Call_3(func, tp, args, kw);

            if (obj == IntPtr.Zero)
            {
                return(IntPtr.Zero);
            }

            var init = Runtime.PyObject_GetAttrString(obj, "__init__");

            Runtime.PyErr_Clear();

            if (init != IntPtr.Zero)
            {
                IntPtr result = Runtime.PyObject_Call(init, args, kw);
                Runtime.XDecref(init);

                if (result == IntPtr.Zero)
                {
                    Runtime.XDecref(obj);
                    return(IntPtr.Zero);
                }

                Runtime.XDecref(result);
            }

            return(obj);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Metatype __new__ implementation. This is called to create a new
        /// class / type when a reflected class is subclassed.
        /// </summary>
        public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw)
        {
            int len = Runtime.PyTuple_Size(args);

            if (len < 3)
            {
                return(Exceptions.RaiseTypeError("invalid argument list"));
            }

            IntPtr name  = Runtime.PyTuple_GetItem(args, 0);
            IntPtr bases = Runtime.PyTuple_GetItem(args, 1);
            IntPtr dict  = Runtime.PyTuple_GetItem(args, 2);

            // We do not support multiple inheritance, so the bases argument
            // should be a 1-item tuple containing the type we are subtyping.
            // That type must itself have a managed implementation. We check
            // that by making sure its metatype is the CLR metatype.

            if (Runtime.PyTuple_Size(bases) != 1)
            {
                return(Exceptions.RaiseTypeError("cannot use multiple inheritance with managed classes"));
            }

            IntPtr base_type = Runtime.PyTuple_GetItem(bases, 0);
            IntPtr mt        = Runtime.PyObject_TYPE(base_type);

            if (!(mt == PyCLRMetaType || mt == Runtime.PyTypeType))
            {
                return(Exceptions.RaiseTypeError("invalid metatype"));
            }

            // Ensure that the reflected type is appropriate for subclassing,
            // disallowing subclassing of delegates, enums and array types.

            var cb = GetManagedObject(base_type) as ClassBase;

            if (cb != null)
            {
                if (!cb.CanSubclass())
                {
                    return(Exceptions.RaiseTypeError("delegates, enums and array types cannot be subclassed"));
                }
            }

            IntPtr slots = Runtime.PyDict_GetItemString(dict, "__slots__");

            if (slots != IntPtr.Zero)
            {
                return(Exceptions.RaiseTypeError("subclasses of managed classes do not support __slots__"));
            }

            // If __assembly__ or __namespace__ are in the class dictionary then create
            // a managed sub type.
            // This creates a new managed type that can be used from .net to call back
            // into python.
            if (IntPtr.Zero != dict)
            {
                Runtime.XIncref(dict);
                using (var clsDict = new PyDict(dict))
                {
                    if (clsDict.HasKey("__assembly__") || clsDict.HasKey("__namespace__"))
                    {
                        return(TypeManager.CreateSubType(name, base_type, dict));
                    }
                }
            }

            // otherwise just create a basic type without reflecting back into the managed side.
            IntPtr func = Marshal.ReadIntPtr(Runtime.PyTypeType, TypeOffset.tp_new);
            IntPtr type = NativeCall.Call_3(func, tp, args, kw);

            if (type == IntPtr.Zero)
            {
                return(IntPtr.Zero);
            }

            int flags = TypeFlags.Default;

            flags |= TypeFlags.Managed;
            flags |= TypeFlags.HeapType;
            flags |= TypeFlags.BaseType;
            flags |= TypeFlags.Subclass;
            flags |= TypeFlags.HaveGC;
            Util.WriteCLong(type, TypeOffset.tp_flags, flags);

            TypeManager.CopySlot(base_type, type, TypeOffset.tp_dealloc);

            // Hmm - the standard subtype_traverse, clear look at ob_size to
            // do things, so to allow gc to work correctly we need to move
            // our hidden handle out of ob_size. Then, in theory we can
            // comment this out and still not crash.
            TypeManager.CopySlot(base_type, type, TypeOffset.tp_traverse);
            TypeManager.CopySlot(base_type, type, TypeOffset.tp_clear);


            // for now, move up hidden handle...
            IntPtr gc = Marshal.ReadIntPtr(base_type, TypeOffset.magic());

            Marshal.WriteIntPtr(type, TypeOffset.magic(), gc);

            return(type);
        }
Exemplo n.º 5
0
        public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw)
        {
            int len = Runtime.PyTuple_Size(args);

            if (len < 3)
            {
                return(Exceptions.RaiseTypeError("invalid argument list"));
            }

            IntPtr name  = Runtime.PyTuple_GetItem(args, 0);
            IntPtr bases = Runtime.PyTuple_GetItem(args, 1);
            IntPtr dict  = Runtime.PyTuple_GetItem(args, 2);

            // We do not support multiple inheritance, so the bases argument
            // should be a 1-item tuple containing the type we are subtyping.
            // That type must itself have a managed implementation. We check
            // that by making sure its metatype is the CLR metatype.

            if (Runtime.PyTuple_Size(bases) != 1)
            {
                return(Exceptions.RaiseTypeError(
                           "cannot use multiple inheritance with managed classes"
                           ));
            }

            IntPtr base_type = Runtime.PyTuple_GetItem(bases, 0);
            IntPtr mt        = Runtime.PyObject_TYPE(base_type);

            if (!((mt == PyCLRMetaType) || (mt == Runtime.PyTypeType)))
            {
                return(Exceptions.RaiseTypeError("invalid metatype"));
            }

            // Ensure that the reflected type is appropriate for subclassing,
            // disallowing subclassing of delegates, enums and array types.

            ClassBase cb = GetManagedObject(base_type) as ClassBase;

            if (cb != null)
            {
                if (!cb.CanSubclass())
                {
                    return(Exceptions.RaiseTypeError(
                               "delegates, enums and array types cannot be subclassed"
                               ));
                }
            }

            IntPtr slots = Runtime.PyDict_GetItemString(dict, "__slots__");

            if (slots != IntPtr.Zero)
            {
                return(Exceptions.RaiseTypeError(
                           "subclasses of managed classes do not support __slots__"
                           ));
            }

            // hack for now... fix for 1.0
            //return TypeManager.CreateSubType(args);


            // right way

            IntPtr func = Marshal.ReadIntPtr(Runtime.PyTypeType,
                                             TypeOffset.tp_new);
            IntPtr type = NativeCall.Call_3(func, tp, args, kw);

            if (type == IntPtr.Zero)
            {
                return(IntPtr.Zero);
            }

            int flags = TypeFlags.Default;

            flags |= TypeFlags.Managed;
            flags |= TypeFlags.HeapType;
            flags |= TypeFlags.BaseType;
            flags |= TypeFlags.Subclass;
            flags |= TypeFlags.HaveGC;
            Marshal.WriteIntPtr(type, TypeOffset.tp_flags, (IntPtr)flags);

            TypeManager.CopySlot(base_type, type, TypeOffset.tp_dealloc);

            // Hmm - the standard subtype_traverse, clear look at ob_size to
            // do things, so to allow gc to work correctly we need to move
            // our hidden handle out of ob_size. Then, in theory we can
            // comment this out and still not crash.
            TypeManager.CopySlot(base_type, type, TypeOffset.tp_traverse);
            TypeManager.CopySlot(base_type, type, TypeOffset.tp_clear);


            // for now, move up hidden handle...
            IntPtr gc = Marshal.ReadIntPtr(base_type, TypeOffset.magic());

            Marshal.WriteIntPtr(type, TypeOffset.magic(), gc);

            //DebugUtil.DumpType(base_type);
            //DebugUtil.DumpType(type);

            return(type);
        }