diff --git a/src/runtime/clrobject.cs b/src/runtime/clrobject.cs index 5c7ad7891..26a52cece 100644 --- a/src/runtime/clrobject.cs +++ b/src/runtime/clrobject.cs @@ -11,8 +11,8 @@ internal CLRObject(object ob, IntPtr tp) { IntPtr py = Runtime.PyType_GenericAlloc(tp, 0); - long flags = Util.ReadCLong(tp, TypeOffset.tp_flags); - if ((flags & TypeFlags.Subclass) != 0) + var flags = (TypeFlags)Util.ReadCLong(tp, TypeOffset.tp_flags); + if (flags.HasFlag(TypeFlags.Subclass)) { IntPtr dict = Marshal.ReadIntPtr(py, ObjectOffset.TypeDictOffset(tp)); if (dict == IntPtr.Zero) diff --git a/src/runtime/interop.cs b/src/runtime/interop.cs index 95f3e5b9f..7d8c2ac2e 100644 --- a/src/runtime/interop.cs +++ b/src/runtime/interop.cs @@ -5,7 +5,6 @@ using System.Runtime.InteropServices; using System.Reflection; using System.Text; -using System.Collections.Generic; namespace Python.Runtime { @@ -69,21 +68,49 @@ public ModulePropertyAttribute() } } - internal static class ManagedDataOffsets + internal static partial class TypeOffset { - static ManagedDataOffsets() + static TypeOffset() { - FieldInfo[] fi = typeof(ManagedDataOffsets).GetFields(BindingFlags.Static | BindingFlags.Public); - for (int i = 0; i < fi.Length; i++) + Type type = typeof(TypeOffset); + FieldInfo[] fields = type.GetFields(); + int size = IntPtr.Size; + for (int i = 0; i < fields.Length; i++) { - fi[i].SetValue(null, -(i * IntPtr.Size) - IntPtr.Size); + int offset = i * size; + FieldInfo fi = fields[i]; + fi.SetValue(null, offset); } + } + + public static int magic() => ManagedDataOffsets.Magic; + } + + internal static class ManagedDataOffsets + { + public static int Magic { get; private set; } - size = fi.Length * IntPtr.Size; + static class DataOffsets + { + public static readonly int ob_data; + public static readonly int ob_dict; + + static DataOffsets() + { + FieldInfo[] fields = typeof(DataOffsets).GetFields(BindingFlags.Static | BindingFlags.Public); + for (int i = 0; i < fields.Length; i++) + { + fields[i].SetValue(null, -(i * IntPtr.Size) - IntPtr.Size); + } + } } - public static readonly int ob_data; - public static readonly int ob_dict; + static ManagedDataOffsets() + { + Magic = TypeOffset.members; + FieldInfo[] fields = typeof(DataOffsets).GetFields(BindingFlags.Static | BindingFlags.Public); + size = fields.Length * IntPtr.Size; + } private static int BaseOffset(IntPtr type) { @@ -102,6 +129,8 @@ public static int DictOffset(IntPtr type) return BaseOffset(type) + ob_dict; } + public static int ob_data => DataOffsets.ob_data; + public static int ob_dict => DataOffsets.ob_dict; public static int Size { get { return size; } } private static readonly int size; @@ -318,38 +347,39 @@ public static void FreeModuleDef(IntPtr ptr) /// Note that the two values reserved for stackless have been put /// to good use as PythonNet specific flags (Managed and Subclass) /// - internal class TypeFlags + [Flags] + internal enum TypeFlags { - public static int HeapType = (1 << 9); - public static int BaseType = (1 << 10); - public static int Ready = (1 << 12); - public static int Readying = (1 << 13); - public static int HaveGC = (1 << 14); + HeapType = (1 << 9), + BaseType = (1 << 10), + Ready = (1 << 12), + Readying = (1 << 13), + HaveGC = (1 << 14), // 15 and 16 are reserved for stackless - public static int HaveStacklessExtension = 0; + HaveStacklessExtension = 0, /* XXX Reusing reserved constants */ - public static int Managed = (1 << 15); // PythonNet specific - public static int Subclass = (1 << 16); // PythonNet specific - public static int HaveIndex = (1 << 17); + Managed = (1 << 15), // PythonNet specific + Subclass = (1 << 16), // PythonNet specific + HaveIndex = (1 << 17), /* Objects support nb_index in PyNumberMethods */ - public static int HaveVersionTag = (1 << 18); - public static int ValidVersionTag = (1 << 19); - public static int IsAbstract = (1 << 20); - public static int HaveNewBuffer = (1 << 21); + HaveVersionTag = (1 << 18), + ValidVersionTag = (1 << 19), + IsAbstract = (1 << 20), + HaveNewBuffer = (1 << 21), // TODO: Implement FastSubclass functions - public static int IntSubclass = (1 << 23); - public static int LongSubclass = (1 << 24); - public static int ListSubclass = (1 << 25); - public static int TupleSubclass = (1 << 26); - public static int StringSubclass = (1 << 27); - public static int UnicodeSubclass = (1 << 28); - public static int DictSubclass = (1 << 29); - public static int BaseExceptionSubclass = (1 << 30); - public static int TypeSubclass = (1 << 31); - - public static int Default = ( + IntSubclass = (1 << 23), + LongSubclass = (1 << 24), + ListSubclass = (1 << 25), + TupleSubclass = (1 << 26), + StringSubclass = (1 << 27), + UnicodeSubclass = (1 << 28), + DictSubclass = (1 << 29), + BaseExceptionSubclass = (1 << 30), + TypeSubclass = (1 << 31), + + Default = ( HaveStacklessExtension | - HaveVersionTag); + HaveVersionTag) } diff --git a/src/runtime/interop36.cs b/src/runtime/interop36.cs index c46bcc2f5..536168275 100644 --- a/src/runtime/interop36.cs +++ b/src/runtime/interop36.cs @@ -12,25 +12,9 @@ namespace Python.Runtime { - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] - internal class TypeOffset + [StructLayout(LayoutKind.Sequential)] + internal static partial class TypeOffset { - static TypeOffset() - { - Type type = typeof(TypeOffset); - FieldInfo[] fi = type.GetFields(); - int size = IntPtr.Size; - for (int i = 0; i < fi.Length; i++) - { - fi[i].SetValue(null, i * size); - } - } - - public static int magic() - { - return ob_size; - } - // Auto-generated from PyHeapTypeObject in Python.h public static int ob_refcnt = 0; public static int ob_type = 0; diff --git a/src/runtime/interop37.cs b/src/runtime/interop37.cs index d5fc76ad3..beb2bb5c9 100644 --- a/src/runtime/interop37.cs +++ b/src/runtime/interop37.cs @@ -12,25 +12,9 @@ namespace Python.Runtime { - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] - internal class TypeOffset + [StructLayout(LayoutKind.Sequential)] + internal static partial class TypeOffset { - static TypeOffset() - { - Type type = typeof(TypeOffset); - FieldInfo[] fi = type.GetFields(); - int size = IntPtr.Size; - for (int i = 0; i < fi.Length; i++) - { - fi[i].SetValue(null, i * size); - } - } - - public static int magic() - { - return ob_size; - } - // Auto-generated from PyHeapTypeObject in Python.h public static int ob_refcnt = 0; public static int ob_type = 0; diff --git a/src/runtime/interop38.cs b/src/runtime/interop38.cs index 9126bca6a..1180962ff 100644 --- a/src/runtime/interop38.cs +++ b/src/runtime/interop38.cs @@ -13,25 +13,9 @@ namespace Python.Runtime { - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] - internal class TypeOffset + [StructLayout(LayoutKind.Sequential)] + internal static partial class TypeOffset { - static TypeOffset() - { - Type type = typeof(TypeOffset); - FieldInfo[] fi = type.GetFields(); - int size = IntPtr.Size; - for (int i = 0; i < fi.Length; i++) - { - fi[i].SetValue(null, i * size); - } - } - - public static int magic() - { - return ob_size; - } - // Auto-generated from PyHeapTypeObject in Python.h public static int ob_refcnt = 0; public static int ob_type = 0; diff --git a/src/runtime/managedtype.cs b/src/runtime/managedtype.cs index afa3bf2d7..6ff2a73ef 100644 --- a/src/runtime/managedtype.cs +++ b/src/runtime/managedtype.cs @@ -29,7 +29,7 @@ internal static ManagedType GetManagedObject(IntPtr ob) } var flags = Util.ReadCLong(tp, TypeOffset.tp_flags); - if ((flags & TypeFlags.Managed) != 0) + if ((flags & (int)TypeFlags.Managed) != 0) { IntPtr op = tp == ob ? Marshal.ReadIntPtr(tp, TypeOffset.magic()) @@ -86,11 +86,8 @@ internal static bool IsManagedType(IntPtr ob) tp = ob; } - var flags = Util.ReadCLong(tp, TypeOffset.tp_flags); - if ((flags & TypeFlags.Managed) != 0) - { - return true; - } + var flags = (TypeFlags)Util.ReadCLong(tp, TypeOffset.tp_flags); + return flags.HasFlag(TypeFlags.Managed); } return false; } diff --git a/src/runtime/metatype.cs b/src/runtime/metatype.cs index 5af2e1a7e..5175964e0 100644 --- a/src/runtime/metatype.cs +++ b/src/runtime/metatype.cs @@ -99,13 +99,13 @@ public static IntPtr tp_new(IntPtr tp, IntPtr args, IntPtr kw) return IntPtr.Zero; } - int flags = TypeFlags.Default; + TypeFlags 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); + Util.WriteCLong(type, TypeOffset.tp_flags, (int)flags); TypeManager.CopySlot(base_type, type, TypeOffset.tp_dealloc); @@ -238,7 +238,7 @@ public static void tp_dealloc(IntPtr tp) // Fix this when we dont cheat on the handle for subclasses! var flags = Util.ReadCLong(tp, TypeOffset.tp_flags); - if ((flags & TypeFlags.Subclass) == 0) + if ((flags & (int)TypeFlags.Subclass) == 0) { IntPtr gc = Marshal.ReadIntPtr(tp, TypeOffset.magic()); ((GCHandle)gc).Free(); diff --git a/src/runtime/typemanager.cs b/src/runtime/typemanager.cs index 985f7f19a..c5de7e3fa 100644 --- a/src/runtime/typemanager.cs +++ b/src/runtime/typemanager.cs @@ -92,9 +92,9 @@ internal static IntPtr CreateType(Type impl) InitializeSlots(type, impl); - int flags = TypeFlags.Default | TypeFlags.Managed | + TypeFlags flags = TypeFlags.Default | TypeFlags.Managed | TypeFlags.HeapType | TypeFlags.HaveGC; - Util.WriteCLong(type, TypeOffset.tp_flags, flags); + Util.WriteCLong(type, TypeOffset.tp_flags, (int)flags); Runtime.PyType_Ready(type); @@ -177,12 +177,12 @@ internal static IntPtr CreateType(ManagedType impl, Type clrType) Runtime.XIncref(base_); } - int flags = TypeFlags.Default; + TypeFlags flags = TypeFlags.Default; flags |= TypeFlags.Managed; flags |= TypeFlags.HeapType; flags |= TypeFlags.BaseType; flags |= TypeFlags.HaveGC; - Util.WriteCLong(type, TypeOffset.tp_flags, flags); + Util.WriteCLong(type, TypeOffset.tp_flags, (int)flags); // Leverage followup initialization from the Python runtime. Note // that the type of the new type must PyType_Type at the time we @@ -349,11 +349,11 @@ internal static IntPtr CreateMetaType(Type impl) InitializeSlots(type, impl); - int flags = TypeFlags.Default; + TypeFlags flags = TypeFlags.Default; flags |= TypeFlags.Managed; flags |= TypeFlags.HeapType; flags |= TypeFlags.HaveGC; - Util.WriteCLong(type, TypeOffset.tp_flags, flags); + Util.WriteCLong(type, TypeOffset.tp_flags, (int)flags); // We need space for 3 PyMethodDef structs, each of them // 4 int-ptrs in size. @@ -408,11 +408,11 @@ internal static IntPtr BasicSubType(string name, IntPtr base_, Type impl) Marshal.WriteIntPtr(type, TypeOffset.tp_base, base_); Runtime.XIncref(base_); - int flags = TypeFlags.Default; + TypeFlags flags = TypeFlags.Default; flags |= TypeFlags.Managed; flags |= TypeFlags.HeapType; flags |= TypeFlags.HaveGC; - Util.WriteCLong(type, TypeOffset.tp_flags, flags); + Util.WriteCLong(type, TypeOffset.tp_flags, (int)flags); CopySlot(base_, type, TypeOffset.tp_traverse); CopySlot(base_, type, TypeOffset.tp_clear); diff --git a/tools/geninterop/geninterop.py b/tools/geninterop/geninterop.py index 902296229..86305dd57 100644 --- a/tools/geninterop/geninterop.py +++ b/tools/geninterop/geninterop.py @@ -243,25 +243,9 @@ def gen_interop_code(members): namespace Python.Runtime { - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] - internal class TypeOffset + [StructLayout(LayoutKind.Sequential)] + internal static partial class TypeOffset { - static TypeOffset() - { - Type type = typeof(TypeOffset); - FieldInfo[] fi = type.GetFields(); - int size = IntPtr.Size; - for (int i = 0; i < fi.Length; i++) - { - fi[i].SetValue(null, i * size); - } - } - - public static int magic() - { - return ob_size; - } - // Auto-generated from PyHeapTypeObject in Python.h """ % (filename, defines_str)