11using System ;
22using System . Collections ;
33using System . Collections . Generic ;
4+ using System . Diagnostics ;
45using System . Runtime . InteropServices ;
56using System . Reflection ;
67using System . Text ;
@@ -67,11 +68,47 @@ 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+ }
7080
71- [ StructLayout ( LayoutKind . Sequential , CharSet = CharSet . Ansi ) ]
72- internal class ObjectOffset
81+ size = fi . Length * IntPtr . Size ;
82+ }
83+
84+ public static readonly int ob_data ;
85+ public static readonly int ob_dict ;
86+
87+ private 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+ private static readonly int size ;
107+ }
108+
109+ internal static class OriginalObjectOffsets
73110 {
74- static ObjectOffset ( )
111+ static OriginalObjectOffsets ( )
75112 {
76113 int size = IntPtr . Size ;
77114 var n = 0 ; // Py_TRACE_REFS add two pointers to PyObject_HEAD
@@ -82,39 +119,58 @@ static ObjectOffset()
82119#endif
83120 ob_refcnt = ( n + 0 ) * size ;
84121 ob_type = ( n + 1 ) * size ;
85- ob_dict = ( n + 2 ) * size ;
86- ob_data = ( n + 3 ) * size ;
87122 }
88123
89- public static int magic ( IntPtr ob )
124+ public static int Size { get { return size ; } }
125+
126+ private static readonly int size =
127+ #if PYTHON_WITH_PYDEBUG
128+ 4 * IntPtr . Size ;
129+ #else
130+ 2 * IntPtr . Size ;
131+ #endif
132+
133+ #if PYTHON_WITH_PYDEBUG
134+ public static int _ob_next ;
135+ public static int _ob_prev ;
136+ #endif
137+ public static int ob_refcnt ;
138+ public static int ob_type ;
139+ }
140+
141+ [ StructLayout ( LayoutKind . Sequential , CharSet = CharSet . Ansi ) ]
142+ internal class ObjectOffset
143+ {
144+ static ObjectOffset ( )
145+ {
146+ #if PYTHON_WITH_PYDEBUG
147+ _ob_next = OriginalObjectOffsets . _ob_next ;
148+ _ob_prev = OriginalObjectOffsets . _ob_prev ;
149+ #endif
150+ ob_refcnt = OriginalObjectOffsets . ob_refcnt ;
151+ ob_type = OriginalObjectOffsets . ob_type ;
152+
153+ size = OriginalObjectOffsets . Size + ManagedDataOffsets . Size ;
154+ }
155+
156+ public static int magic ( IntPtr type )
90157 {
91- if ( IsException ( ob ) )
92- {
93- return ExceptionOffset . ob_data ;
94- }
95- return ob_data ;
158+ return ManagedDataOffsets . DataOffset ( type ) ;
96159 }
97160
98- public static int DictOffset ( IntPtr ob )
161+ public static int TypeDictOffset ( IntPtr type )
99162 {
100- if ( IsException ( ob ) )
101- {
102- return ExceptionOffset . ob_dict ;
103- }
104- return ob_dict ;
163+ return ManagedDataOffsets . DictOffset ( type ) ;
105164 }
106165
107- public static int Size ( IntPtr ob )
166+ public static int Size ( IntPtr pyType )
108167 {
109- if ( IsException ( ob ) )
168+ if ( IsException ( pyType ) )
110169 {
111170 return ExceptionOffset . Size ( ) ;
112171 }
113- #if PYTHON_WITH_PYDEBUG
114- return 6 * IntPtr . Size ;
115- #else
116- return 4 * IntPtr . Size ;
117- #endif
172+
173+ return size ;
118174 }
119175
120176#if PYTHON_WITH_PYDEBUG
@@ -123,8 +179,7 @@ public static int Size(IntPtr ob)
123179#endif
124180 public static int ob_refcnt ;
125181 public static int ob_type ;
126- private static int ob_dict ;
127- private static int ob_data ;
182+ private static readonly int size ;
128183
129184 private static bool IsException ( IntPtr pyObject )
130185 {
@@ -141,19 +196,17 @@ internal class ExceptionOffset
141196 static ExceptionOffset ( )
142197 {
143198 Type type = typeof ( ExceptionOffset ) ;
144- FieldInfo [ ] fi = type . GetFields ( ) ;
145- int size = IntPtr . Size ;
199+ FieldInfo [ ] fi = type . GetFields ( BindingFlags . Static | BindingFlags . Public ) ;
146200 for ( int i = 0 ; i < fi . Length ; i ++ )
147201 {
148- fi [ i ] . SetValue ( null , ( i * size ) + ObjectOffset . ob_type + size ) ;
202+ fi [ i ] . SetValue ( null , ( i * IntPtr . Size ) + OriginalObjectOffsets . Size ) ;
149203 }
150- }
151204
152- public static int Size ( )
153- {
154- return ob_data + IntPtr . Size ;
205+ size = fi . Length * IntPtr . Size + OriginalObjectOffsets . Size + ManagedDataOffsets . Size ;
155206 }
156207
208+ public static int Size ( ) { return size ; }
209+
157210 // PyException_HEAD
158211 // (start after PyObject_HEAD)
159212 public static int dict = 0 ;
@@ -167,9 +220,7 @@ public static int Size()
167220 public static int suppress_context = 0 ;
168221#endif
169222
170- // extra c# data
171- public static int ob_dict ;
172- public static int ob_data ;
223+ private static readonly int size ;
173224 }
174225
175226
0 commit comments