42
42
43
43
import static com .oracle .graal .python .builtins .PythonBuiltinClassType .SystemError ;
44
44
import static com .oracle .graal .python .nodes .SpecialAttributeNames .__FILE__ ;
45
- import static com .oracle .graal .python .runtime .exception .PythonErrorType .ImportError ;
46
45
import static com .oracle .graal .python .runtime .exception .PythonErrorType .NotImplementedError ;
47
46
48
47
import java .io .IOException ;
75
74
import com .oracle .graal .python .builtins .objects .object .PythonObjectLibrary ;
76
75
import com .oracle .graal .python .builtins .objects .str .PString ;
77
76
import com .oracle .graal .python .nodes .ErrorMessages ;
77
+ import com .oracle .graal .python .nodes .PConstructAndRaiseNode ;
78
78
import com .oracle .graal .python .nodes .SpecialMethodNames ;
79
79
import com .oracle .graal .python .nodes .attributes .ReadAttributeFromObjectNode ;
80
80
import com .oracle .graal .python .nodes .attributes .SetAttributeNode ;
@@ -203,6 +203,24 @@ public abstract static class CreateDynamic extends PythonBuiltinNode {
203
203
@ Child private SetItemNode setItemNode ;
204
204
@ Child private CheckFunctionResultNode checkResultNode ;
205
205
@ Child private LookupAndCallUnaryNode callReprNode = LookupAndCallUnaryNode .create (SpecialMethodNames .__REPR__ );
206
+ @ Child private PConstructAndRaiseNode constructAndRaiseNode ;
207
+
208
+ static class ImportException extends Exception {
209
+ private static final long serialVersionUID = 3517291912314595890L ;
210
+ public final PBaseException cause ;
211
+ public final Object name ;
212
+ public final Object path ;
213
+ public final String formatString ;
214
+ public final Object [] formatArgs ;
215
+
216
+ ImportException (PBaseException cause , Object name , Object path , String formatString , Object ... formatArgs ) {
217
+ this .cause = cause ;
218
+ this .name = name ;
219
+ this .path = path ;
220
+ this .formatString = formatString ;
221
+ this .formatArgs = formatArgs ;
222
+ }
223
+ }
206
224
207
225
@ Specialization
208
226
@ SuppressWarnings ("try" )
@@ -212,13 +230,15 @@ public Object run(VirtualFrame frame, PythonObject moduleSpec, @SuppressWarnings
212
230
Object state = ForeignCallContext .enter (frame , context , this );
213
231
try {
214
232
return run (moduleSpec , interop );
233
+ } catch (ImportException ie ) {
234
+ throw getConstructAndRaiseNode ().raiseImportError (frame , ie .cause , ie .name , ie .path , ie .formatString , ie .formatArgs );
215
235
} finally {
216
236
ForeignCallContext .exit (frame , context , state );
217
237
}
218
238
}
219
239
220
240
@ TruffleBoundary
221
- private Object run (PythonObject moduleSpec , InteropLibrary interop ) {
241
+ private Object run (PythonObject moduleSpec , InteropLibrary interop ) throws ImportException {
222
242
String name = moduleSpec .getAttribute ("name" ).toString ();
223
243
String path = moduleSpec .getAttribute ("origin" ).toString ();
224
244
@@ -238,9 +258,9 @@ private Object findExtensionObject(String name, String path) {
238
258
}
239
259
240
260
@ TruffleBoundary
241
- private Object loadDynamicModuleWithSpec (String name , String path , InteropLibrary interop ) {
261
+ private Object loadDynamicModuleWithSpec (String name , String path , InteropLibrary interop ) throws ImportException {
242
262
// we always need to load the CPython C API (even for HPy modules)
243
- ensureCapiWasLoaded ();
263
+ ensureCapiWasLoaded (name , path );
244
264
PythonContext context = getContext ();
245
265
Env env = context .getEnv ();
246
266
String basename = name .substring (name .lastIndexOf ('.' ) + 1 );
@@ -251,9 +271,9 @@ private Object loadDynamicModuleWithSpec(String name, String path, InteropLibrar
251
271
sulongLibrary = (TruffleObject ) callTarget .call ();
252
272
} catch (SecurityException | IOException e ) {
253
273
logJavaException (e );
254
- throw raise ( ImportError , wrapJavaException (e ), ErrorMessages .CANNOT_LOAD_M , path , e );
274
+ throw new ImportException ( wrapJavaException (e ), name , path , ErrorMessages .CANNOT_LOAD_M , path , e );
255
275
} catch (RuntimeException e ) {
256
- throw reportImportError (e , path );
276
+ throw reportImportError (e , name , path );
257
277
}
258
278
259
279
// Now, try to detect the C extension's API by looking for the appropriate init
@@ -267,23 +287,23 @@ private Object loadDynamicModuleWithSpec(String name, String path, InteropLibrar
267
287
return initCApiModule (sulongLibrary , initFuncName , name , path , interop );
268
288
} catch (UnsupportedTypeException | ArityException | UnsupportedMessageException e ) {
269
289
logJavaException (e );
270
- throw raise ( ImportError , wrapJavaException (e ), ErrorMessages .CANNOT_INITIALIZE_WITH , path , basename , "" );
290
+ throw new ImportException ( wrapJavaException (e ), name , path , ErrorMessages .CANNOT_INITIALIZE_WITH , path , basename , "" );
271
291
} catch (RuntimeException e ) {
272
- throw reportImportError (e , path );
292
+ throw reportImportError (e , name , path );
273
293
}
274
294
}
275
295
276
296
@ TruffleBoundary
277
297
private Object initHPyModule (TruffleObject sulongLibrary , String initFuncName , String name , String path , InteropLibrary interop )
278
- throws UnsupportedMessageException , ArityException , UnsupportedTypeException {
298
+ throws UnsupportedMessageException , ArityException , UnsupportedTypeException , ImportException {
279
299
PythonContext context = getContext ();
280
- GraalHPyContext hpyContext = ensureHPyWasLoaded (context );
300
+ GraalHPyContext hpyContext = ensureHPyWasLoaded (context , name , path );
281
301
282
302
TruffleObject pyinitFunc ;
283
303
try {
284
304
pyinitFunc = (TruffleObject ) interop .readMember (sulongLibrary , initFuncName );
285
305
} catch (UnknownIdentifierException | UnsupportedMessageException e1 ) {
286
- throw raise ( ImportError , ErrorMessages .NO_FUNCTION_FOUND , "" , initFuncName , path );
306
+ throw new ImportException ( null , name , path , ErrorMessages .NO_FUNCTION_FOUND , "" , initFuncName , path );
287
307
}
288
308
Object nativeResult = interop .execute (pyinitFunc , hpyContext );
289
309
getCheckResultNode ().execute (initFuncName , nativeResult );
@@ -304,13 +324,13 @@ private Object initHPyModule(TruffleObject sulongLibrary, String initFuncName, S
304
324
305
325
@ TruffleBoundary
306
326
private Object initCApiModule (TruffleObject sulongLibrary , String initFuncName , String name , String path , InteropLibrary interop )
307
- throws UnsupportedMessageException , ArityException , UnsupportedTypeException {
327
+ throws UnsupportedMessageException , ArityException , UnsupportedTypeException , ImportException {
308
328
PythonContext context = getContext ();
309
329
TruffleObject pyinitFunc ;
310
330
try {
311
331
pyinitFunc = (TruffleObject ) interop .readMember (sulongLibrary , initFuncName );
312
332
} catch (UnknownIdentifierException | UnsupportedMessageException e1 ) {
313
- throw raise ( ImportError , ErrorMessages .NO_FUNCTION_FOUND , "" , initFuncName , path );
333
+ throw new ImportException ( null , name , path , ErrorMessages .NO_FUNCTION_FOUND , "" , initFuncName , path );
314
334
}
315
335
Object nativeResult = interop .execute (pyinitFunc );
316
336
getCheckResultNode ().execute (initFuncName , nativeResult );
@@ -330,11 +350,11 @@ private Object initCApiModule(TruffleObject sulongLibrary, String initFuncName,
330
350
}
331
351
332
352
@ TruffleBoundary
333
- private void ensureCapiWasLoaded () {
353
+ private void ensureCapiWasLoaded (String name , String path ) throws ImportException {
334
354
PythonContext context = getContext ();
335
355
if (!context .hasCApiContext ()) {
336
356
if (!context .getEnv ().isNativeAccessAllowed ()) {
337
- throw raise ( ImportError , ErrorMessages .NATIVE_ACCESS_NOT_ALLOWED );
357
+ throw new ImportException ( null , name , path , ErrorMessages .NATIVE_ACCESS_NOT_ALLOWED );
338
358
}
339
359
340
360
Env env = context .getEnv ();
@@ -352,7 +372,7 @@ private void ensureCapiWasLoaded() {
352
372
capi = context .getEnv ().parseInternal (capiSrcBuilder .build ()).call ();
353
373
} catch (IOException | RuntimeException e ) {
354
374
logJavaException (e );
355
- throw raise ( ImportError , wrapJavaException (e ), ErrorMessages .CAPI_LOAD_ERROR , capiFile .getAbsoluteFile ().getPath ());
375
+ throw new ImportException ( wrapJavaException (e ), name , path , ErrorMessages .CAPI_LOAD_ERROR , capiFile .getAbsoluteFile ().getPath ());
356
376
}
357
377
try {
358
378
// call into Python to initialize python_cext module globals
@@ -369,13 +389,13 @@ private void ensureCapiWasLoaded() {
369
389
callNode .executeObject (null , readNode .execute (builtinModule , IMPORT_NATIVE_MEMORYVIEW ), capi );
370
390
} catch (RuntimeException e ) {
371
391
logJavaException (e );
372
- throw raise ( ImportError , wrapJavaException (e ), ErrorMessages .CAPI_LOAD_ERROR , capiFile .getAbsoluteFile ().getPath ());
392
+ throw new ImportException ( wrapJavaException (e ), name , path , ErrorMessages .CAPI_LOAD_ERROR , capiFile .getAbsoluteFile ().getPath ());
373
393
}
374
394
}
375
395
}
376
396
377
397
@ TruffleBoundary
378
- private GraalHPyContext ensureHPyWasLoaded (PythonContext context ) {
398
+ private GraalHPyContext ensureHPyWasLoaded (PythonContext context , String name , String path ) throws ImportException {
379
399
if (!context .hasHPyContext ()) {
380
400
Env env = context .getEnv ();
381
401
CompilerDirectives .transferToInterpreterAndInvalidate ();
@@ -395,7 +415,7 @@ private GraalHPyContext ensureHPyWasLoaded(PythonContext context) {
395
415
interopLibrary .invokeMember (hpyLibrary , "graal_hpy_init" , new GraalHPyInitObject (context .getHPyContext ()));
396
416
} catch (IOException | RuntimeException | InteropException e ) {
397
417
logJavaException (e );
398
- throw raise ( ImportError , wrapJavaException (e ), ErrorMessages .HPY_LOAD_ERROR , capiFile .getAbsoluteFile ().getPath ());
418
+ throw new ImportException ( wrapJavaException (e ), name , path , ErrorMessages .HPY_LOAD_ERROR , capiFile .getAbsoluteFile ().getPath ());
399
419
}
400
420
}
401
421
return context .getHPyContext ();
@@ -435,8 +455,16 @@ private CheckFunctionResultNode getCheckResultNode() {
435
455
return checkResultNode ;
436
456
}
437
457
458
+ private PConstructAndRaiseNode getConstructAndRaiseNode () {
459
+ if (constructAndRaiseNode == null ) {
460
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
461
+ constructAndRaiseNode = insert (PConstructAndRaiseNode .create ());
462
+ }
463
+ return constructAndRaiseNode ;
464
+ }
465
+
438
466
@ TruffleBoundary
439
- private PException reportImportError (RuntimeException e , String path ) {
467
+ private PException reportImportError (RuntimeException e , String name , String path ) throws ImportException {
440
468
StringBuilder sb = new StringBuilder ();
441
469
PBaseException pythonCause = null ;
442
470
if (e instanceof PException ) {
@@ -465,9 +493,9 @@ private PException reportImportError(RuntimeException e, String path) {
465
493
}
466
494
Object [] args = new Object []{path , sb .toString ()};
467
495
if (pythonCause != null ) {
468
- throw raise ( ImportError , pythonCause , ErrorMessages .CANNOT_LOAD , args );
496
+ throw new ImportException ( pythonCause , name , path , ErrorMessages .CANNOT_LOAD , args );
469
497
} else {
470
- throw raise ( ImportError , ErrorMessages .CANNOT_LOAD , args );
498
+ throw new ImportException ( null , name , path , ErrorMessages .CANNOT_LOAD , args );
471
499
}
472
500
}
473
501
}
0 commit comments