11#nullable enable
22using System ;
33using System . Diagnostics ;
4- using System . Runtime . InteropServices ;
54
65using Python . Runtime . Native ;
76
@@ -24,12 +23,16 @@ internal PyType(BorrowedReference reference, bool prevalidated = false) : base(r
2423 {
2524 if ( prevalidated ) return ;
2625
27- if ( ! Runtime . PyType_Check ( this . Handle ) )
26+ if ( ! Runtime . PyType_Check ( this ) )
2827 throw new ArgumentException ( "object is not a type" ) ;
2928 }
3029
31- internal PyType ( in StolenReference reference ) : base ( EnsureIsType ( in reference ) )
30+ internal PyType ( in StolenReference reference , bool prevalidated = false ) : base ( reference )
3231 {
32+ if ( prevalidated ) return ;
33+
34+ if ( ! Runtime . PyType_Check ( this ) )
35+ throw new ArgumentException ( "object is not a type" ) ;
3336 }
3437
3538 internal new static PyType ? FromNullableReference ( BorrowedReference reference )
@@ -46,7 +49,7 @@ public string Name
4649 {
4750 var namePtr = new StrPtr
4851 {
49- RawPointer = Marshal . ReadIntPtr ( Handle , TypeOffset . tp_name ) ,
52+ RawPointer = Util . ReadIntPtr ( this , TypeOffset . tp_name ) ,
5053 } ;
5154 return namePtr . ToString ( System . Text . Encoding . UTF8 ) ! ;
5255 }
@@ -57,8 +60,8 @@ public string Name
5760
5861 internal TypeFlags Flags
5962 {
60- get => ( TypeFlags ) Util . ReadCLong ( Handle , TypeOffset . tp_flags ) ;
61- set => Util . WriteCLong ( Handle , TypeOffset . tp_flags , ( long ) value ) ;
63+ get => ( TypeFlags ) Util . ReadCLong ( this , TypeOffset . tp_flags ) ;
64+ set => Util . WriteCLong ( this , TypeOffset . tp_flags , ( long ) value ) ;
6265 }
6366
6467 /// <summary>Checks if specified object is a Python type.</summary>
@@ -71,7 +74,7 @@ public static bool IsType(PyObject value)
7174 /// <summary>Checks if specified object is a Python type.</summary>
7275 internal static bool IsType ( BorrowedReference value )
7376 {
74- return Runtime . PyType_Check ( value . DangerousGetAddress ( ) ) ;
77+ return Runtime . PyType_Check ( value ) ;
7578 }
7679
7780 /// <summary>
@@ -90,16 +93,7 @@ public static PyType Get(Type clrType)
9093 internal BorrowedReference BaseReference
9194 {
9295 get => GetBase ( Reference ) ;
93- set
94- {
95- var old = BaseReference . DangerousGetAddressOrNull ( ) ;
96- IntPtr @new = value . DangerousGetAddress ( ) ;
97-
98- Runtime . XIncref ( @new ) ;
99- Marshal . WriteIntPtr ( Handle , TypeOffset . tp_base , @new ) ;
100-
101- Runtime . XDecref ( old ) ;
102- }
96+ set => Runtime . ReplaceReference ( this , TypeOffset . tp_base , new NewReference ( value ) . Steal ( ) ) ;
10397 }
10498
10599 internal IntPtr GetSlot ( TypeSlotID slot )
@@ -122,37 +116,21 @@ internal static void SetFlags(BorrowedReference type, TypeFlags flags)
122116 internal static BorrowedReference GetBase ( BorrowedReference type )
123117 {
124118 Debug . Assert ( IsType ( type ) ) ;
125- IntPtr basePtr = Marshal . ReadIntPtr ( type . DangerousGetAddress ( ) , TypeOffset . tp_base ) ;
126- return new BorrowedReference ( basePtr ) ;
119+ return Util . ReadRef ( type , TypeOffset . tp_base ) ;
127120 }
128121
129122 internal static BorrowedReference GetBases ( BorrowedReference type )
130123 {
131124 Debug . Assert ( IsType ( type ) ) ;
132- IntPtr basesPtr = Marshal . ReadIntPtr ( type . DangerousGetAddress ( ) , TypeOffset . tp_bases ) ;
133- return new BorrowedReference ( basesPtr ) ;
125+ return Util . ReadRef ( type , TypeOffset . tp_bases ) ;
134126 }
135127
136128 internal static BorrowedReference GetMRO ( BorrowedReference type )
137129 {
138130 Debug . Assert ( IsType ( type ) ) ;
139- IntPtr basesPtr = Marshal . ReadIntPtr ( type . DangerousGetAddress ( ) , TypeOffset . tp_mro ) ;
140- return new BorrowedReference ( basesPtr ) ;
131+ return Util . ReadRef ( type , TypeOffset . tp_mro ) ;
141132 }
142133
143- private static IntPtr EnsureIsType ( in StolenReference reference )
144- {
145- IntPtr address = reference . DangerousGetAddressOrNull ( ) ;
146- if ( address == IntPtr . Zero )
147- throw new ArgumentNullException ( nameof ( reference ) ) ;
148- return EnsureIsType ( address ) ;
149- }
150-
151- private static IntPtr EnsureIsType ( IntPtr ob )
152- => Runtime . PyType_Check ( ob )
153- ? ob
154- : throw new ArgumentException ( "object is not a type" ) ;
155-
156134 private static BorrowedReference FromObject ( PyObject o )
157135 {
158136 if ( o is null ) throw new ArgumentNullException ( nameof ( o ) ) ;
@@ -161,22 +139,17 @@ private static BorrowedReference FromObject(PyObject o)
161139 return o . Reference ;
162140 }
163141
164- private static IntPtr FromSpec ( TypeSpec spec , PyTuple ? bases = null )
142+ private static StolenReference FromSpec ( TypeSpec spec , PyTuple ? bases = null )
165143 {
166144 if ( spec is null ) throw new ArgumentNullException ( nameof ( spec ) ) ;
167145
168146 if ( ( spec . Flags & TypeFlags . HeapType ) == 0 )
169147 throw new NotSupportedException ( "Only heap types are supported" ) ;
170148
171- var nativeSpec = new NativeTypeSpec ( spec ) ;
149+ using var nativeSpec = new NativeTypeSpec ( spec ) ;
172150 var basesRef = bases is null ? default : bases . Reference ;
173151 var result = Runtime . PyType_FromSpecWithBases ( in nativeSpec , basesRef ) ;
174-
175- PythonException . ThrowIfIsNull ( result ) ;
176-
177- nativeSpec . Dispose ( ) ;
178-
179- return result . DangerousMoveToPointer ( ) ;
152+ return result . StealOrThrow ( ) ;
180153 }
181154 }
182155}
0 commit comments