@@ -88,7 +88,7 @@ internal static IntPtr CreateType(Type impl)
8888 // Set tp_basicsize to the size of our managed instance objects.
8989 Marshal . WriteIntPtr ( type , TypeOffset . tp_basicsize , ( IntPtr ) ob_size ) ;
9090
91- var offset = ( IntPtr ) ObjectOffset . TypeDictOffset ( type ) ;
91+ var offset = ( IntPtr ) ObjectOffset . TypeDictOffset ( ) ;
9292 Marshal . WriteIntPtr ( type , TypeOffset . tp_dictoffset , offset ) ;
9393
9494 InitializeSlots ( type , impl ) ;
@@ -109,21 +109,11 @@ internal static IntPtr CreateType(Type impl)
109109 return type ;
110110 }
111111
112-
113112 internal static IntPtr CreateType ( ManagedType impl , Type clrType )
114113 {
115114 string name = GetPythonTypeName ( clrType ) ;
116115
117116 int ob_size ;
118- int tp_dictoffset = ObjectOffset . TypeDictOffset ( Runtime . PyTypeType ) ;
119-
120- // XXX Hack, use a different base class for System.Exception
121- // Python 2.5+ allows new style class exceptions but they *must*
122- // subclass BaseException (or better Exception).
123- if ( typeof ( Exception ) . IsAssignableFrom ( clrType ) )
124- {
125- tp_dictoffset = ObjectOffset . TypeDictOffset ( Exceptions . Exception ) ;
126- }
127117
128118 IntPtr type = AllocateTypeObject ( name , typeType : Runtime . PyCLRMetaType ) ;
129119
@@ -159,22 +149,29 @@ internal static IntPtr CreateType(ManagedType impl, Type clrType)
159149 Marshal . WriteIntPtr ( type , TypeOffset . tp_bases , baseTuple . Reference . DangerousIncRefOrNull ( ) ) ;
160150 }
161151
162- int baseSize = primaryBase == Runtime . PyBaseObjectType ? ObjectOffset . PyObject_HEAD_Size ( )
163- : primaryBase == Exceptions . Exception ? ExceptionOffset . Size ( )
164- : checked ( ( int ) Marshal . ReadIntPtr ( primaryBase , TypeOffset . tp_basicsize ) ) ;
165- if ( ! ManagedType . IsManagedType ( primaryBase ) )
166- {
152+ ob_size = checked ( ( int ) Marshal . ReadIntPtr ( primaryBase , TypeOffset . tp_basicsize ) ) ;
153+ void InheritOrAllocate ( int typeField ) {
154+ int value = Marshal . ReadInt32 ( primaryBase , typeField ) ;
155+ if ( value == 0 ) {
156+ Marshal . WriteIntPtr ( type , typeField , new IntPtr ( ob_size ) ) ;
157+ ob_size += IntPtr . Size ;
158+ } else {
159+ Marshal . WriteIntPtr ( type , typeField , new IntPtr ( value ) ) ;
160+ }
161+ }
162+
163+ InheritOrAllocate ( TypeOffset . tp_dictoffset ) ;
164+ InheritOrAllocate ( TypeOffset . tp_weaklistoffset ) ;
165+
166+ if ( ! ManagedType . IsManagedType ( primaryBase ) ) {
167167 // base type is a Python type, so we must allocate additional space for GC handle
168- extraTypeDataOffset = baseSize ;
168+ extraTypeDataOffset = ob_size ;
169169 ObjectOffset . ClrGcHandleOffsetAssertSanity ( extraTypeDataOffset ) ;
170- ob_size = baseSize + MetaType . ExtraTypeDataSize ;
171- } else
172- {
170+ ob_size += MetaType . ExtraTypeDataSize ;
171+ } else {
173172 extraTypeDataOffset = checked ( ( int ) Marshal . ReadIntPtr ( primaryBase , TypeOffset . clr_gchandle_offset ) ) ;
174173 ObjectOffset . ClrGcHandleOffsetAssertSanity ( extraTypeDataOffset ) ;
175- ob_size = baseSize ;
176174 }
177- Debug . Assert ( extraTypeDataOffset > tp_dictoffset ) ;
178175 }
179176 catch ( Exception error )
180177 {
@@ -186,7 +183,6 @@ internal static IntPtr CreateType(ManagedType impl, Type clrType)
186183
187184 Marshal . WriteIntPtr ( type , TypeOffset . tp_basicsize , ( IntPtr ) ob_size ) ;
188185 Marshal . WriteIntPtr ( type , TypeOffset . tp_itemsize , IntPtr . Zero ) ;
189- Marshal . WriteIntPtr ( type , TypeOffset . tp_dictoffset , ( IntPtr ) tp_dictoffset ) ;
190186 Marshal . WriteIntPtr ( type , TypeOffset . clr_gchandle_offset , ( IntPtr ) extraTypeDataOffset ) ;
191187
192188 var flags = TypeFlags . Default ;
@@ -206,6 +202,8 @@ internal static IntPtr CreateType(ManagedType impl, Type clrType)
206202 return IntPtr . Zero ;
207203 }
208204
205+ Debug . Assert ( extraTypeDataOffset > Marshal . ReadInt32 ( type , TypeOffset . tp_dictoffset ) ) ;
206+
209207 IntPtr dict = Marshal . ReadIntPtr ( type , TypeOffset . tp_dict ) ;
210208 string mn = clrType . Namespace ?? "" ;
211209 IntPtr mod = Runtime . PyString_FromString ( mn ) ;
0 commit comments