25
25
*/
26
26
package com .oracle .graal .python .nodes .statement ;
27
27
28
+ import static com .oracle .graal .python .nodes .SpecialAttributeNames .__NAME__ ;
28
29
import static com .oracle .graal .python .nodes .SpecialMethodNames .__GETATTRIBUTE__ ;
29
30
import static com .oracle .graal .python .runtime .exception .PythonErrorType .ImportError ;
30
31
31
32
import com .oracle .graal .python .builtins .objects .function .PArguments ;
33
+ import com .oracle .graal .python .builtins .objects .str .PString ;
34
+ import com .oracle .graal .python .nodes .attributes .GetAttributeNode ;
35
+ import com .oracle .graal .python .nodes .attributes .ReadAttributeFromObjectNode ;
32
36
import com .oracle .graal .python .nodes .call .special .LookupAndCallBinaryNode ;
33
37
import com .oracle .graal .python .nodes .frame .WriteNode ;
38
+ import com .oracle .graal .python .nodes .object .IsBuiltinClassProfile ;
39
+ import com .oracle .graal .python .nodes .subscript .GetItemNode ;
34
40
import com .oracle .graal .python .runtime .exception .PException ;
41
+ import com .oracle .truffle .api .CompilerDirectives ;
35
42
import com .oracle .truffle .api .frame .VirtualFrame ;
36
43
import com .oracle .truffle .api .nodes .ExplodeLoop ;
37
44
@@ -40,7 +47,11 @@ public class ImportFromNode extends AbstractImportNode {
40
47
private final int level ;
41
48
private final String [] fromlist ;
42
49
@ Children private final WriteNode [] aslist ;
50
+ @ Child private GetAttributeNode getName ;
51
+ @ Child private GetItemNode getItem ;
52
+ @ Child private ReadAttributeFromObjectNode readModules ;
43
53
@ Child private LookupAndCallBinaryNode readNode = LookupAndCallBinaryNode .create (__GETATTRIBUTE__ );
54
+ private final IsBuiltinClassProfile attrErrorProfile = IsBuiltinClassProfile .create ();
44
55
45
56
public static ImportFromNode create (String importee , String [] fromlist , WriteNode [] readNodes , int level ) {
46
57
return new ImportFromNode (importee , fromlist , readNodes , level );
@@ -68,7 +79,32 @@ public void executeVoid(VirtualFrame frame) {
68
79
try {
69
80
writeNode .doWrite (frame , readNode .executeObject (importedModule , attr ));
70
81
} catch (PException e ) {
71
- throw raise (ImportError , "cannot import name '%s'" , attr );
82
+ e .expectAttributeError (attrErrorProfile );
83
+ if (getName == null ) {
84
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
85
+ getName = insert (GetAttributeNode .create (__NAME__ , null ));
86
+ }
87
+ try {
88
+ String pkgname ;
89
+ Object pkgname_o = getName .executeObject (importedModule );
90
+ if (pkgname_o instanceof PString ) {
91
+ pkgname = ((PString ) pkgname_o ).getValue ();
92
+ } else if (pkgname_o instanceof String ) {
93
+ pkgname = (String ) pkgname_o ;
94
+ } else {
95
+ throw e ;
96
+ }
97
+ String fullname = pkgname + "." + attr ;
98
+ if (getItem == null ) {
99
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
100
+ getItem = insert (GetItemNode .create ());
101
+ readModules = insert (ReadAttributeFromObjectNode .create ());
102
+ }
103
+ Object sysModules = readModules .execute (getCore ().lookupBuiltinModule ("sys" ), "modules" );
104
+ writeNode .doWrite (frame , getItem .execute (sysModules , fullname ));
105
+ } catch (PException e2 ) {
106
+ throw raise (ImportError , "cannot import name '%s'" , attr );
107
+ }
72
108
}
73
109
}
74
110
}
0 commit comments