1
1
using System ;
2
2
using System . Collections ;
3
- using System . Collections . Specialized ;
3
+ using System . Collections . Generic ;
4
+ using System . Diagnostics ;
4
5
using System . Runtime . InteropServices ;
5
6
using System . Reflection ;
6
7
using System . Text ;
@@ -67,11 +68,47 @@ public ModulePropertyAttribute()
67
68
}
68
69
}
69
70
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
+ }
70
80
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
73
110
{
74
- static ObjectOffset ( )
111
+ static OriginalObjectOffsets ( )
75
112
{
76
113
int size = IntPtr . Size ;
77
114
var n = 0 ; // Py_TRACE_REFS add two pointers to PyObject_HEAD
@@ -82,42 +119,58 @@ static ObjectOffset()
82
119
#endif
83
120
ob_refcnt = ( n + 0 ) * size ;
84
121
ob_type = ( n + 1 ) * size ;
85
- ob_dict = ( n + 2 ) * size ;
86
- ob_data = ( n + 3 ) * size ;
87
122
}
88
123
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 ( )
90
145
{
91
- if ( ( Runtime . PyObject_TypeCheck ( ob , Exceptions . BaseException ) ||
92
- ( Runtime . PyType_Check ( ob ) && Runtime . PyType_IsSubtype ( ob , Exceptions . BaseException ) ) ) )
93
- {
94
- return ExceptionOffset . ob_data ;
95
- }
96
- return ob_data ;
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 ;
97
154
}
98
155
99
- public static int DictOffset ( IntPtr ob )
156
+ public static int magic ( IntPtr type )
100
157
{
101
- if ( ( Runtime . PyObject_TypeCheck ( ob , Exceptions . BaseException ) ||
102
- ( Runtime . PyType_Check ( ob ) && Runtime . PyType_IsSubtype ( ob , Exceptions . BaseException ) ) ) )
103
- {
104
- return ExceptionOffset . ob_dict ;
105
- }
106
- return ob_dict ;
158
+ return ManagedDataOffsets . DataOffset ( type ) ;
107
159
}
108
160
109
- public static int Size ( IntPtr ob )
161
+ public static int TypeDictOffset ( IntPtr type )
110
162
{
111
- if ( ( Runtime . PyObject_TypeCheck ( ob , Exceptions . BaseException ) ||
112
- ( Runtime . PyType_Check ( ob ) && Runtime . PyType_IsSubtype ( ob , Exceptions . BaseException ) ) ) )
163
+ return ManagedDataOffsets . DictOffset ( type ) ;
164
+ }
165
+
166
+ public static int Size ( IntPtr pyType )
167
+ {
168
+ if ( IsException ( pyType ) )
113
169
{
114
170
return ExceptionOffset . Size ( ) ;
115
171
}
116
- #if PYTHON_WITH_PYDEBUG
117
- return 6 * IntPtr . Size ;
118
- #else
119
- return 4 * IntPtr . Size ;
120
- #endif
172
+
173
+ return size ;
121
174
}
122
175
123
176
#if PYTHON_WITH_PYDEBUG
@@ -126,8 +179,15 @@ public static int Size(IntPtr ob)
126
179
#endif
127
180
public static int ob_refcnt ;
128
181
public static int ob_type ;
129
- private static int ob_dict ;
130
- private static int ob_data ;
182
+ private static readonly int size ;
183
+
184
+ private static bool IsException ( IntPtr pyObject )
185
+ {
186
+ var type = Runtime . PyObject_TYPE ( pyObject ) ;
187
+ return Runtime . PyObjectType_TypeCheck ( type , Exceptions . BaseException )
188
+ || Runtime . PyObjectType_TypeCheck ( type , Runtime . PyTypeType )
189
+ && Runtime . PyType_IsSubtype ( pyObject , Exceptions . BaseException ) ;
190
+ }
131
191
}
132
192
133
193
[ StructLayout ( LayoutKind . Sequential , CharSet = CharSet . Ansi ) ]
@@ -136,19 +196,17 @@ internal class ExceptionOffset
136
196
static ExceptionOffset ( )
137
197
{
138
198
Type type = typeof ( ExceptionOffset ) ;
139
- FieldInfo [ ] fi = type . GetFields ( ) ;
140
- int size = IntPtr . Size ;
199
+ FieldInfo [ ] fi = type . GetFields ( BindingFlags . Static | BindingFlags . Public ) ;
141
200
for ( int i = 0 ; i < fi . Length ; i ++ )
142
201
{
143
- fi [ i ] . SetValue ( null , ( i * size ) + ObjectOffset . ob_type + size ) ;
202
+ fi [ i ] . SetValue ( null , ( i * IntPtr . Size ) + OriginalObjectOffsets . Size ) ;
144
203
}
145
- }
146
204
147
- public static int Size ( )
148
- {
149
- return ob_data + IntPtr . Size ;
205
+ size = fi . Length * IntPtr . Size + OriginalObjectOffsets . Size + ManagedDataOffsets . Size ;
150
206
}
151
207
208
+ public static int Size ( ) { return size ; }
209
+
152
210
// PyException_HEAD
153
211
// (start after PyObject_HEAD)
154
212
public static int dict = 0 ;
@@ -162,9 +220,7 @@ public static int Size()
162
220
public static int suppress_context = 0 ;
163
221
#endif
164
222
165
- // extra c# data
166
- public static int ob_dict ;
167
- public static int ob_data ;
223
+ private static readonly int size ;
168
224
}
169
225
170
226
0 commit comments