@@ -13,6 +13,7 @@ internal static class ImportHook
13
13
private static CLRModule root ;
14
14
private static MethodWrapper hook ;
15
15
private static IntPtr py_clr_module ;
16
+ static BorrowedReference ClrModuleReference => new BorrowedReference ( py_clr_module ) ;
16
17
17
18
private static IntPtr module_def = IntPtr . Zero ;
18
19
@@ -74,7 +75,7 @@ static void RestoreImport()
74
75
/// <summary>
75
76
/// Initialization performed on startup of the Python runtime.
76
77
/// </summary>
77
- internal static void Initialize ( )
78
+ internal static unsafe void Initialize ( )
78
79
{
79
80
InitImport ( ) ;
80
81
@@ -86,14 +87,13 @@ internal static void Initialize()
86
87
py_clr_module = Runtime . PyModule_Create2 ( module_def , 3 ) ;
87
88
88
89
// both dicts are borrowed references
89
- IntPtr mod_dict = Runtime . PyModule_GetDict ( py_clr_module ) ;
90
- IntPtr clr_dict = Runtime . _PyObject_GetDictPtr ( root . pyHandle ) ; // PyObject**
91
- clr_dict = ( IntPtr ) Marshal . PtrToStructure ( clr_dict , typeof ( IntPtr ) ) ;
90
+ BorrowedReference mod_dict = Runtime . PyModule_GetDict ( ClrModuleReference ) ;
91
+ BorrowedReference clr_dict = * Runtime . _PyObject_GetDictPtr ( root . ObjectReference ) ;
92
92
93
93
Runtime . PyDict_Update ( mod_dict , clr_dict ) ;
94
- IntPtr dict = Runtime . PyImport_GetModuleDict ( ) ;
95
- Runtime . PyDict_SetItemString ( dict , "CLR" , py_clr_module ) ;
96
- Runtime . PyDict_SetItemString ( dict , "clr" , py_clr_module ) ;
94
+ BorrowedReference dict = Runtime . PyImport_GetModuleDict ( ) ;
95
+ Runtime . PyDict_SetItemString ( dict , "CLR" , ClrModuleReference ) ;
96
+ Runtime . PyDict_SetItemString ( dict , "clr" , ClrModuleReference ) ;
97
97
}
98
98
99
99
@@ -143,67 +143,62 @@ internal static void RestoreRuntimeData(RuntimeDataStorage storage)
143
143
/// <summary>
144
144
/// Return the clr python module (new reference)
145
145
/// </summary>
146
- public static IntPtr GetCLRModule ( IntPtr ? fromList = null )
146
+ public static unsafe NewReference GetCLRModule ( BorrowedReference fromList = default )
147
147
{
148
148
root . InitializePreload ( ) ;
149
149
150
150
// update the module dictionary with the contents of the root dictionary
151
151
root . LoadNames ( ) ;
152
- IntPtr py_mod_dict = Runtime . PyModule_GetDict ( py_clr_module ) ;
153
- IntPtr clr_dict = Runtime . _PyObject_GetDictPtr ( root . pyHandle ) ; // PyObject**
154
- clr_dict = ( IntPtr ) Marshal . PtrToStructure ( clr_dict , typeof ( IntPtr ) ) ;
152
+ BorrowedReference py_mod_dict = Runtime . PyModule_GetDict ( ClrModuleReference ) ;
153
+ BorrowedReference clr_dict = * Runtime . _PyObject_GetDictPtr ( root . ObjectReference ) ;
155
154
Runtime . PyDict_Update ( py_mod_dict , clr_dict ) ;
156
155
157
156
// find any items from the from list and get them from the root if they're not
158
157
// already in the module dictionary
159
- if ( fromList != null && fromList != IntPtr . Zero )
158
+ if ( fromList != null && fromList != default )
160
159
{
161
- if ( Runtime . PyTuple_Check ( fromList . GetValueOrDefault ( ) ) )
160
+ if ( Runtime . PyTuple_Check ( fromList ) )
162
161
{
163
- Runtime . XIncref ( py_mod_dict ) ;
164
- using ( var mod_dict = new PyDict ( py_mod_dict ) )
162
+ using var mod_dict = new PyDict ( py_mod_dict ) ;
163
+ using var from = new PyTuple ( fromList ) ;
164
+ foreach ( PyObject item in from )
165
165
{
166
- Runtime . XIncref ( fromList . GetValueOrDefault ( ) ) ;
167
- using ( var from = new PyTuple ( fromList . GetValueOrDefault ( ) ) )
166
+ if ( mod_dict . HasKey ( item ) )
168
167
{
169
- foreach ( PyObject item in from )
170
- {
171
- if ( mod_dict . HasKey ( item ) )
172
- {
173
- continue ;
174
- }
175
-
176
- var s = item . AsManagedObject ( typeof ( string ) ) as string ;
177
- if ( s == null )
178
- {
179
- continue ;
180
- }
181
-
182
- ManagedType attr = root . GetAttribute ( s , true ) ;
183
- if ( attr == null )
184
- {
185
- continue ;
186
- }
187
-
188
- Runtime . XIncref ( attr . pyHandle ) ;
189
- using ( var obj = new PyObject ( attr . pyHandle ) )
190
- {
191
- mod_dict . SetItem ( s , obj ) ;
192
- }
193
- }
168
+ continue ;
169
+ }
170
+
171
+ var s = item . AsManagedObject ( typeof ( string ) ) as string ;
172
+ if ( s == null )
173
+ {
174
+ continue ;
175
+ }
176
+
177
+ ManagedType attr = root . GetAttribute ( s , true ) ;
178
+ if ( attr == null )
179
+ {
180
+ continue ;
181
+ }
182
+
183
+ Runtime . XIncref ( attr . pyHandle ) ;
184
+ using ( var obj = new PyObject ( attr . pyHandle ) )
185
+ {
186
+ mod_dict . SetItem ( s , obj ) ;
194
187
}
195
188
}
196
189
}
197
190
}
198
191
Runtime . XIncref ( py_clr_module ) ;
199
- return py_clr_module ;
192
+ return NewReference . DangerousFromPointer ( py_clr_module ) ;
200
193
}
201
194
202
195
/// <summary>
203
196
/// The actual import hook that ties Python to the managed world.
204
197
/// </summary>
205
- public static IntPtr __import__ ( IntPtr self , IntPtr args , IntPtr kw )
198
+ public static IntPtr __import__ ( IntPtr self , IntPtr argsRaw , IntPtr kw )
206
199
{
200
+ var args = new BorrowedReference ( argsRaw ) ;
201
+
207
202
// Replacement for the builtin __import__. The original import
208
203
// hook is saved as this.py_import. This version handles CLR
209
204
// import and defers to the normal builtin for everything else.
@@ -214,9 +209,8 @@ public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw)
214
209
return Exceptions . RaiseTypeError ( "__import__() takes at least 1 argument (0 given)" ) ;
215
210
}
216
211
217
- // borrowed reference
218
- IntPtr py_mod_name = Runtime . PyTuple_GetItem ( args , 0 ) ;
219
- if ( py_mod_name == IntPtr . Zero ||
212
+ BorrowedReference py_mod_name = Runtime . PyTuple_GetItem ( args , 0 ) ;
213
+ if ( py_mod_name . IsNull ||
220
214
! Runtime . IsStringType ( py_mod_name ) )
221
215
{
222
216
return Exceptions . RaiseTypeError ( "string expected" ) ;
@@ -225,12 +219,12 @@ public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw)
225
219
// Check whether the import is of the form 'from x import y'.
226
220
// This determines whether we return the head or tail module.
227
221
228
- IntPtr fromList = IntPtr . Zero ;
222
+ BorrowedReference fromList = default ;
229
223
var fromlist = false ;
230
224
if ( num_args >= 4 )
231
225
{
232
226
fromList = Runtime . PyTuple_GetItem ( args , 3 ) ;
233
- if ( fromList != IntPtr . Zero &&
227
+ if ( fromList != default &&
234
228
Runtime . PyObject_IsTrue ( fromList ) == 1 )
235
229
{
236
230
fromlist = true ;
@@ -243,16 +237,16 @@ public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw)
243
237
// the module.
244
238
if ( mod_name == "clr" )
245
239
{
246
- IntPtr clr_module = GetCLRModule ( fromList ) ;
247
- if ( clr_module != IntPtr . Zero )
240
+ NewReference clr_module = GetCLRModule ( fromList ) ;
241
+ if ( ! clr_module . IsNull ( ) )
248
242
{
249
- IntPtr sys_modules = Runtime . PyImport_GetModuleDict ( ) ;
250
- if ( sys_modules != IntPtr . Zero )
243
+ BorrowedReference sys_modules = Runtime . PyImport_GetModuleDict ( ) ;
244
+ if ( ! sys_modules . IsNull )
251
245
{
252
246
Runtime . PyDict_SetItemString ( sys_modules , "clr" , clr_module ) ;
253
247
}
254
248
}
255
- return clr_module ;
249
+ return clr_module . DangerousMoveToPointerOrNull ( ) ;
256
250
}
257
251
258
252
string realname = mod_name ;
@@ -265,7 +259,7 @@ public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw)
265
259
// Turns out that the AssemblyManager.ResolveHandler() checks to see if any
266
260
// Assembly's FullName.ToLower().StartsWith(name.ToLower()), which makes very
267
261
// little sense to me.
268
- IntPtr res = Runtime . PyObject_Call ( py_import , args , kw ) ;
262
+ IntPtr res = Runtime . PyObject_Call ( py_import , args . DangerousGetAddress ( ) , kw ) ;
269
263
if ( res != IntPtr . Zero )
270
264
{
271
265
// There was no error.
@@ -300,10 +294,10 @@ public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw)
300
294
301
295
// See if sys.modules for this interpreter already has the
302
296
// requested module. If so, just return the existing module.
303
- IntPtr modules = Runtime . PyImport_GetModuleDict ( ) ;
304
- IntPtr module = Runtime . PyDict_GetItem ( modules , py_mod_name ) ;
297
+ BorrowedReference modules = Runtime . PyImport_GetModuleDict ( ) ;
298
+ BorrowedReference module = Runtime . PyDict_GetItem ( modules , py_mod_name ) ;
305
299
306
- if ( module != IntPtr . Zero )
300
+ if ( module != default )
307
301
{
308
302
if ( fromlist )
309
303
{
@@ -312,16 +306,15 @@ public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw)
312
306
var mod = ManagedType . GetManagedObject ( module ) as ModuleObject ;
313
307
mod ? . LoadNames ( ) ;
314
308
}
315
- Runtime . XIncref ( module ) ;
316
- return module ;
309
+ return Runtime . NewRef ( module ) . DangerousMoveToPointer ( ) ;
317
310
}
318
311
if ( clr_prefix != null )
319
312
{
320
- return GetCLRModule ( fromList ) ;
313
+ return GetCLRModule ( fromList ) . DangerousMoveToPointerOrNull ( ) ;
321
314
}
322
315
module = Runtime . PyDict_GetItemString ( modules , names [ 0 ] ) ;
323
- Runtime . XIncref ( module ) ;
324
- return module ;
316
+ return Runtime . NewRefOrNull ( module )
317
+ . DangerousMoveToPointer ( ) ;
325
318
}
326
319
Exceptions . Clear ( ) ;
327
320
@@ -358,12 +351,12 @@ public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw)
358
351
}
359
352
360
353
// Add the module to sys.modules
361
- Runtime . PyDict_SetItemString ( modules , tail . moduleName , tail . pyHandle ) ;
354
+ Runtime . PyDict_SetItemString ( modules , tail . moduleName , tail . ObjectReference ) ;
362
355
363
356
// If imported from CLR add clr.<modulename> to sys.modules as well
364
357
if ( clr_prefix != null )
365
358
{
366
- Runtime . PyDict_SetItemString ( modules , clr_prefix + tail . moduleName , tail . pyHandle ) ;
359
+ Runtime . PyDict_SetItemString ( modules , clr_prefix + tail . moduleName , tail . ObjectReference ) ;
367
360
}
368
361
}
369
362
@@ -380,7 +373,7 @@ public static IntPtr __import__(IntPtr self, IntPtr args, IntPtr kw)
380
373
}
381
374
}
382
375
383
- private static bool IsLoadAll ( IntPtr fromList )
376
+ private static bool IsLoadAll ( BorrowedReference fromList )
384
377
{
385
378
if ( CLRModule . preload )
386
379
{
@@ -390,10 +383,8 @@ private static bool IsLoadAll(IntPtr fromList)
390
383
{
391
384
return false ;
392
385
}
393
- IntPtr fp = Runtime . PySequence_GetItem ( fromList , 0 ) ;
394
- bool res = Runtime . GetManagedString ( fp ) == "*" ;
395
- Runtime . XDecref ( fp ) ;
396
- return res ;
386
+ using var fp = Runtime . PySequence_GetItem ( fromList , 0 ) ;
387
+ return Runtime . GetManagedString ( fp ) == "*" ;
397
388
}
398
389
}
399
390
}
0 commit comments