11using System ;
22using System . Collections ;
33using System . Collections . Generic ;
4+ using System . Diagnostics ;
45using System . Runtime . InteropServices ;
56using System . Reflection ;
67using System . Text ;
@@ -67,6 +68,44 @@ public ModulePropertyAttribute()
6768 }
6869 }
6970
71+ internal static class ManagedDataOffsets
72+ {
73+ static ManagedDataOffsets ( )
74+ {
75+ FieldInfo [ ] fi = typeof ( ManagedDataOffsets ) . GetFields ( BindingFlags . Static | BindingFlags . Public ) ;
76+ for ( int i = 0 ; i < fi . Length ; i ++ )
77+ {
78+ fi [ i ] . SetValue ( null , - ( i * IntPtr . Size ) - IntPtr . Size ) ;
79+ }
80+
81+ size = fi . Length * IntPtr . Size ;
82+ }
83+
84+ public static readonly int ob_data ;
85+ public static readonly int ob_dict ;
86+
87+ static int BaseOffset ( IntPtr type )
88+ {
89+ Debug . Assert ( type != IntPtr . Zero ) ;
90+ int typeSize = Marshal . ReadInt32 ( type , TypeOffset . tp_basicsize ) ;
91+ Debug . Assert ( typeSize > 0 && typeSize <= ExceptionOffset . Size ( ) ) ;
92+ return typeSize ;
93+ }
94+ public static int DataOffset ( IntPtr type )
95+ {
96+ return BaseOffset ( type ) + ob_data ;
97+ }
98+
99+ public static int DictOffset ( IntPtr type )
100+ {
101+ return BaseOffset ( type ) + ob_dict ;
102+ }
103+
104+ public static int Size { get { return size ; } }
105+
106+ static readonly int size ;
107+ }
108+
70109 internal static class OriginalObjectOffsets
71110 {
72111 static OriginalObjectOffsets ( )
@@ -82,13 +121,14 @@ static OriginalObjectOffsets()
82121 ob_type = ( n + 1 ) * size ;
83122 }
84123
85- public static int Size ( ) {
124+ public static int Size { get { return size ; } }
125+
126+ static readonly int size =
86127#if PYTHON_WITH_PYDEBUG
87- return 4 * IntPtr . Size ;
128+ 4 * IntPtr . Size ;
88129#else
89- return 2 * IntPtr . Size ;
130+ 2 * IntPtr . Size ;
90131#endif
91- }
92132
93133#if PYTHON_WITH_PYDEBUG
94134 public static int _ob_next ;
@@ -109,23 +149,28 @@ static ObjectOffset()
109149#endif
110150 ob_refcnt = OriginalObjectOffsets . ob_refcnt ;
111151 ob_type = OriginalObjectOffsets . ob_type ;
112- ob_dict = ExceptionOffset . ob_dict ;
113- ob_data = ExceptionOffset . ob_data ;
152+
153+ size = OriginalObjectOffsets . Size + ManagedDataOffsets . Size ;
114154 }
115155
116- public static int magic ( IntPtr ob )
156+ public static int magic ( IntPtr type )
117157 {
118- return ob_data ;
158+ return ManagedDataOffsets . DataOffset ( type ) ;
119159 }
120160
121- public static int DictOffset ( IntPtr ob )
161+ public static int TypeDictOffset ( IntPtr type )
122162 {
123- return ob_dict ;
163+ return ManagedDataOffsets . DictOffset ( type ) ;
124164 }
125165
126- public static int Size ( IntPtr ob )
166+ public static int Size ( IntPtr pyType )
127167 {
128- return ExceptionOffset . Size ( ) ;
168+ if ( IsException ( pyType ) )
169+ {
170+ return ExceptionOffset . Size ( ) ;
171+ }
172+
173+ return size ;
129174 }
130175
131176#if PYTHON_WITH_PYDEBUG
@@ -134,8 +179,16 @@ public static int Size(IntPtr ob)
134179#endif
135180 public static int ob_refcnt ;
136181 public static int ob_type ;
137- private static int ob_dict ;
138- private static int ob_data ;
182+
183+ static readonly int size ;
184+
185+ private static bool IsException ( IntPtr pyObject )
186+ {
187+ var type = Runtime . PyObject_TYPE ( pyObject ) ;
188+ return Runtime . PyObjectType_TypeCheck ( type , Exceptions . BaseException )
189+ || Runtime . PyObjectType_TypeCheck ( type , Runtime . PyTypeType )
190+ && Runtime . PyType_IsSubtype ( pyObject , Exceptions . BaseException ) ;
191+ }
139192 }
140193
141194 [ StructLayout ( LayoutKind . Sequential , CharSet = CharSet . Ansi ) ]
@@ -147,10 +200,10 @@ static ExceptionOffset()
147200 FieldInfo [ ] fi = type . GetFields ( BindingFlags . Static | BindingFlags . Public ) ;
148201 for ( int i = 0 ; i < fi . Length ; i ++ )
149202 {
150- fi [ i ] . SetValue ( null , ( i * IntPtr . Size ) + OriginalObjectOffsets . Size ( ) ) ;
203+ fi [ i ] . SetValue ( null , ( i * IntPtr . Size ) + OriginalObjectOffsets . Size ) ;
151204 }
152205
153- size = ob_data + IntPtr . Size ;
206+ size = fi . Length * IntPtr . Size + OriginalObjectOffsets . Size + ManagedDataOffsets . Size ;
154207 }
155208
156209 public static int Size ( ) { return size ; }
@@ -168,10 +221,6 @@ static ExceptionOffset()
168221 public static int suppress_context = 0 ;
169222#endif
170223
171- // extra c# data
172- public static int ob_dict ;
173- public static int ob_data ;
174-
175224 static readonly int size ;
176225 }
177226
0 commit comments