102
102
import com .oracle .graal .python .builtins .modules .PosixModuleBuiltins .FsConverterNode ;
103
103
import com .oracle .graal .python .builtins .modules .SysModuleBuiltins .AuditNode ;
104
104
import com .oracle .graal .python .builtins .modules .ctypes .CFieldBuiltins .GetFuncNode ;
105
+ import com .oracle .graal .python .builtins .modules .ctypes .CtypesModuleBuiltinsClinicProviders .DyldSharedCacheContainsPathClinicProviderGen ;
105
106
import com .oracle .graal .python .builtins .modules .ctypes .CtypesNodes .PyTypeCheck ;
106
107
import com .oracle .graal .python .builtins .modules .ctypes .FFIType .FFI_TYPES ;
107
108
import com .oracle .graal .python .builtins .modules .ctypes .FFIType .FieldGet ;
108
109
import com .oracle .graal .python .builtins .modules .ctypes .StgDictBuiltins .PyObjectStgDictNode ;
109
110
import com .oracle .graal .python .builtins .modules .ctypes .StgDictBuiltins .PyTypeStgDictNode ;
110
- import com .oracle .graal .python .builtins .modules .ctypes .CtypesModuleBuiltinsClinicProviders .DyldSharedCacheContainsPathClinicProviderGen ;
111
111
import com .oracle .graal .python .builtins .modules .ctypes .memory .Pointer ;
112
112
import com .oracle .graal .python .builtins .modules .ctypes .memory .PointerNodes ;
113
113
import com .oracle .graal .python .builtins .modules .ctypes .memory .PointerReference ;
131
131
import com .oracle .graal .python .builtins .objects .dict .PDict ;
132
132
import com .oracle .graal .python .builtins .objects .function .PKeyword ;
133
133
import com .oracle .graal .python .builtins .objects .module .PythonModule ;
134
- import com .oracle .graal .python .builtins .objects .str .StringBuiltins .PrefixSuffixNode ;
135
134
import com .oracle .graal .python .builtins .objects .str .StringUtils .SimpleTruffleStringFormatNode ;
136
135
import com .oracle .graal .python .builtins .objects .tuple .PTuple ;
137
136
import com .oracle .graal .python .builtins .objects .type .TypeNodes .GetBaseClassNode ;
204
203
import com .oracle .truffle .api .nodes .Node ;
205
204
import com .oracle .truffle .api .source .Source ;
206
205
import com .oracle .truffle .api .strings .TruffleString ;
207
- import com .oracle .truffle .api .strings .TruffleString .CodePointLengthNode ;
208
206
import com .oracle .truffle .api .strings .TruffleString .EqualNode ;
209
207
import com .oracle .truffle .api .strings .TruffleStringBuilder ;
210
208
import com .oracle .truffle .nfi .api .SignatureLibrary ;
@@ -226,8 +224,6 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
226
224
227
225
private DLHandler rtldDefault ;
228
226
private Object dyldSharedCacheContainsPathFunction ;
229
- @ CompilationFinal private Object strlenFunction ;
230
- @ CompilationFinal private Object memcpyFunction ;
231
227
232
228
protected static final int FUNCFLAG_STDCALL = 0x0 ;
233
229
protected static final int FUNCFLAG_CDECL = 0x1 ;
@@ -272,22 +268,23 @@ public void postInitialize(Python3Core core) {
272
268
273
269
PythonContext context = core .getContext ();
274
270
275
- DLHandler handle ;
271
+ DLHandler handle = null ;
272
+ // We use directly native if available
276
273
if (context .getEnv ().isNativeAccessAllowed ()) {
277
274
handle = DlOpenNode .loadNFILibrary (context , NFIBackend .NATIVE , J_DEFAULT_LIBRARY , rtldLocal );
278
- setCtypeNFIHelpers (this , context , handle );
279
-
280
275
if (PythonOS .getPythonOS () == PythonOS .PLATFORM_WIN32 ) {
281
276
PythonModule sysModule = context .getSysModule ();
282
277
Object loadLibraryMethod = ReadAttributeFromObjectNode .getUncached ().execute (ctypesModule , toTruffleStringUncached ("LoadLibrary" ));
283
278
Object pythonLib = CallNode .executeUncached (loadLibraryMethod , toTruffleStringUncached (GraalHPyJNIContext .getJNILibrary ()), 0 );
284
279
WriteAttributeToPythonObjectNode .getUncached ().execute (sysModule , toTruffleStringUncached ("dllhandle" ), pythonLib );
285
280
}
286
- } else {
281
+ } else if (!PythonOptions .NativeModules .getValue (context .getEnv ().getOptions ())) {
282
+ // If native is not available, we can use the C API support library only if it was
283
+ // loaded through LLVM and not NFI. This limitation can be lifted: we can reload the
284
+ // library with LLVM here.
287
285
try {
288
286
Object llvmLibrary = CApiContext .ensureCApiLLVMLibrary (context );
289
287
handle = new DLHandler (llvmLibrary , 0 , J_EMPTY_STRING , true );
290
- setCtypeLLVMHelpers (this , handle );
291
288
} catch (ApiInitException e ) {
292
289
throw e .reraise (null , null , PConstructAndRaiseNode .Lazy .getUncached ());
293
290
} catch (ImportException e ) {
@@ -296,38 +293,16 @@ public void postInitialize(Python3Core core) {
296
293
throw PConstructAndRaiseNode .getUncached ().raiseOSError (null , e , EqualNode .getUncached ());
297
294
}
298
295
}
299
- NativeFunction memmove = MemMoveFunction .create (handle , context );
300
- ctypesModule .setAttribute (tsLiteral ("_memmove_addr" ), factory .createNativeVoidPtr (memmove , memmove .adr ));
301
- NativeFunction memset = MemSetFunction .create (handle , context );
302
- ctypesModule .setAttribute (tsLiteral ("_memset_addr" ), factory .createNativeVoidPtr (memset , memset .adr ));
303
- rtldDefault = handle ;
304
- }
305
-
306
- Object getStrlenFunction () {
307
- return strlenFunction ;
308
- }
309
-
310
- Object getMemcpyFunction () {
311
- return memcpyFunction ;
312
- }
313
-
314
- private static void setCtypeLLVMHelpers (CtypesModuleBuiltins ctypesModuleBuiltins , DLHandler h ) {
315
- try {
316
- InteropLibrary lib = InteropLibrary .getUncached (h .library );
317
- ctypesModuleBuiltins .strlenFunction = lib .readMember (h .library , NativeCAPISymbol .FUN_STRLEN .getName ());
318
- ctypesModuleBuiltins .memcpyFunction = lib .readMember (h .library , NativeCAPISymbol .FUN_MEMCPY .getName ());
319
- } catch (UnsupportedMessageException | UnknownIdentifierException e ) {
320
- throw CompilerDirectives .shouldNotReachHere ();
321
- }
322
- }
323
-
324
- private static void setCtypeNFIHelpers (CtypesModuleBuiltins ctypesModuleBuiltins , PythonContext context , DLHandler h ) {
325
- try {
326
- ctypesModuleBuiltins .strlenFunction = createNFIHelperFunction (context , h , "strlen" , "(POINTER):UINT32" );
327
- ctypesModuleBuiltins .memcpyFunction = createNFIHelperFunction (context , h , "memcpy" , "([UINT8], POINTER, UINT32):POINTER" );
328
- } catch (UnsupportedMessageException | UnknownIdentifierException e ) {
329
- throw CompilerDirectives .shouldNotReachHere ();
296
+ if (handle != null ) {
297
+ NativeFunction memmove = MemMoveFunction .create (handle , context );
298
+ ctypesModule .setAttribute (tsLiteral ("_memmove_addr" ), factory .createNativeVoidPtr (memmove , memmove .adr ));
299
+ NativeFunction memset = MemSetFunction .create (handle , context );
300
+ ctypesModule .setAttribute (tsLiteral ("_memset_addr" ), factory .createNativeVoidPtr (memset , memset .adr ));
330
301
}
302
+ // If handle == null, and we don't set the attributes, ctypes module is going to fail in
303
+ // __init__.py on importing those attributes from _ctypes. This way the failure will happen
304
+ // only when ctypes are actually imported
305
+ rtldDefault = handle ;
331
306
}
332
307
333
308
@ TruffleBoundary
@@ -734,8 +709,6 @@ static Object py_dl_open(VirtualFrame frame, PythonModule self, TruffleString na
734
709
@ Bind ("this" ) Node inliningTarget ,
735
710
@ Cached PyObjectHashNode hashNode ,
736
711
@ Cached AuditNode auditNode ,
737
- @ Cached CodePointLengthNode codePointLengthNode ,
738
- @ Cached PrefixSuffixNode prefixSuffixNode ,
739
712
@ Cached EqualNode eqNode ,
740
713
@ Cached PythonObjectFactory factory ,
741
714
@ Cached PRaiseNode .Lazy raiseNode ) {
@@ -752,17 +725,14 @@ static Object py_dl_open(VirtualFrame frame, PythonModule self, TruffleString na
752
725
PythonContext context = PythonContext .get (inliningTarget );
753
726
DLHandler handle ;
754
727
Exception exception = null ;
755
- boolean loadWithLLVM = !context .getEnv ().isNativeAccessAllowed () || //
756
- (!context .getOption (PythonOptions .UseSystemToolchain ) &&
757
- prefixSuffixNode .endsWith (name , context .getSoAbi (), 0 , codePointLengthNode .execute (name , TS_ENCODING )));
758
728
try {
759
- if (loadWithLLVM ) {
729
+ if (! context . getEnv (). isNativeAccessAllowed () && ! PythonOptions . NativeModules . getValue ( context . getEnv (). getOptions ()) ) {
760
730
Object handler = loadLLVMLibrary (context , inliningTarget , name );
761
731
long adr = hashNode .execute (frame , inliningTarget , handler );
762
732
handle = new DLHandler (handler , adr , name .toJavaStringUncached (), true );
763
733
registerAddress (context , handle .adr , handle );
764
734
return factory .createNativeVoidPtr (handle );
765
- } else {
735
+ } else if ( context . getEnv (). isNativeAccessAllowed ()) {
766
736
CtypesThreadState ctypes = CtypesThreadState .get (context , PythonLanguage .get (inliningTarget ));
767
737
/*-
768
738
TODO: (mq) cryptography in macos isn't always compatible with ctypes.
0 commit comments