40
40
*/
41
41
package com .oracle .graal .python .builtins .objects .function ;
42
42
43
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .__GETATTRIBUTE__ ;
44
+
43
45
import java .util .Objects ;
44
46
import java .util .concurrent .ConcurrentHashMap ;
45
47
46
48
import com .oracle .graal .python .builtins .Builtin ;
47
49
import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
50
+ import com .oracle .graal .python .builtins .objects .module .ModuleBuiltinsFactory ;
51
+ import com .oracle .graal .python .builtins .objects .object .ObjectBuiltinsFactory ;
48
52
import com .oracle .graal .python .builtins .objects .type .PythonBuiltinClass ;
53
+ import com .oracle .graal .python .builtins .objects .type .TypeBuiltinsFactory ;
49
54
import com .oracle .graal .python .nodes .function .PythonBuiltinBaseNode ;
50
55
import com .oracle .graal .python .nodes .function .builtins .PythonBinaryBuiltinNode ;
51
56
import com .oracle .graal .python .nodes .function .builtins .PythonTernaryBuiltinNode ;
@@ -74,6 +79,10 @@ public abstract class BuiltinMethodDescriptor {
74
79
*/
75
80
private static final ConcurrentHashMap <BuiltinMethodDescriptor , BuiltinMethodDescriptor > CACHE = new ConcurrentHashMap <>();
76
81
82
+ public static final BuiltinMethodDescriptor OBJ_GET_ATTRIBUTE = get (__GETATTRIBUTE__ , ObjectBuiltinsFactory .GetAttributeNodeFactory .getInstance (), PythonBuiltinClassType .PythonObject );
83
+ public static final BuiltinMethodDescriptor MODULE_GET_ATTRIBUTE = get (__GETATTRIBUTE__ , ModuleBuiltinsFactory .ModuleGetattritbuteNodeFactory .getInstance (), PythonBuiltinClassType .PythonModule );
84
+ public static final BuiltinMethodDescriptor TYPE_GET_ATTRIBUTE = get (__GETATTRIBUTE__ , TypeBuiltinsFactory .GetattributeNodeFactory .getInstance (), PythonBuiltinClassType .PythonClass );
85
+
77
86
public static BuiltinMethodDescriptor get (PBuiltinFunction function ) {
78
87
CompilerAsserts .neverPartOfCompilation ();
79
88
NodeFactory <? extends PythonBuiltinBaseNode > factory = function .getBuiltinNodeFactory ();
@@ -91,22 +100,22 @@ public static BuiltinMethodDescriptor get(PBuiltinFunction function) {
91
100
assert enclosing == null ;
92
101
}
93
102
94
- return get (factory , type );
103
+ return get (function . getName (), factory , type );
95
104
}
96
105
97
- public static BuiltinMethodDescriptor get (NodeFactory <? extends PythonBuiltinBaseNode > factory , PythonBuiltinClassType type ) {
106
+ private static BuiltinMethodDescriptor get (String name , NodeFactory <? extends PythonBuiltinBaseNode > factory , PythonBuiltinClassType type ) {
98
107
CompilerAsserts .neverPartOfCompilation ();
99
108
Class <? extends PythonBuiltinBaseNode > nodeClass = factory .getNodeClass ();
100
109
BuiltinMethodDescriptor result = null ;
101
110
if (PythonUnaryBuiltinNode .class .isAssignableFrom (nodeClass )) {
102
- result = new UnaryBuiltinDescriptor (factory , type );
103
- assert result .getBuiltinAnnotation ().minNumOfPositionalArgs () <= 1 : result . getBuiltinAnnotation (). name () ;
111
+ result = new UnaryBuiltinDescriptor (name , factory , type );
112
+ assert result .getBuiltinAnnotation ().minNumOfPositionalArgs () <= 1 : name ;
104
113
} else if (PythonBinaryBuiltinNode .class .isAssignableFrom (nodeClass )) {
105
- result = new BinaryBuiltinDescriptor (factory , type );
106
- assert result .getBuiltinAnnotation ().minNumOfPositionalArgs () <= 2 : result . getBuiltinAnnotation (). name () ;
114
+ result = new BinaryBuiltinDescriptor (name , factory , type );
115
+ assert result .getBuiltinAnnotation ().minNumOfPositionalArgs () <= 2 : name ;
107
116
} else if (PythonTernaryBuiltinNode .class .isAssignableFrom (nodeClass )) {
108
- result = new TernaryBuiltinDescriptor (factory , type );
109
- assert result .getBuiltinAnnotation ().minNumOfPositionalArgs () <= 3 : result . getBuiltinAnnotation (). name () ;
117
+ result = new TernaryBuiltinDescriptor (name , factory , type );
118
+ assert result .getBuiltinAnnotation ().minNumOfPositionalArgs () <= 3 : name ;
110
119
}
111
120
if (result != null ) {
112
121
return CACHE .computeIfAbsent (result , x -> x );
@@ -115,7 +124,7 @@ public static BuiltinMethodDescriptor get(NodeFactory<? extends PythonBuiltinBas
115
124
}
116
125
117
126
public static boolean isInstance (Object obj ) {
118
- return obj instanceof UnaryBuiltinDescriptor || obj instanceof BinaryBuiltinDescriptor || obj instanceof TernaryBuiltinDescriptor ;
127
+ return obj instanceof BuiltinMethodDescriptor ;
119
128
}
120
129
121
130
private static boolean needsFrame (NodeFactory <? extends PythonBuiltinBaseNode > factory ) {
@@ -129,8 +138,12 @@ private static boolean needsFrame(NodeFactory<? extends PythonBuiltinBaseNode> f
129
138
130
139
private final NodeFactory <? extends PythonBuiltinBaseNode > factory ;
131
140
private final PythonBuiltinClassType type ;
141
+ // Name allows us to differentiate between builtins shared for reversible operations, such as
142
+ // int.__mul__ and int.__rmul__, which have the same node factory
143
+ private final String name ;
132
144
133
- private BuiltinMethodDescriptor (NodeFactory <? extends PythonBuiltinBaseNode > factory , PythonBuiltinClassType type ) {
145
+ private BuiltinMethodDescriptor (String name , NodeFactory <? extends PythonBuiltinBaseNode > factory , PythonBuiltinClassType type ) {
146
+ this .name = name ;
134
147
this .factory = factory ;
135
148
this .type = type ;
136
149
}
@@ -139,33 +152,42 @@ public final NodeFactory<? extends PythonBuiltinBaseNode> getFactory() {
139
152
return factory ;
140
153
}
141
154
142
- public Builtin getBuiltinAnnotation () {
155
+ public final PythonBuiltinClassType getEnclosingType () {
156
+ return type ;
157
+ }
158
+
159
+ public final String getName () {
160
+ return name ;
161
+ }
162
+
163
+ public final Builtin getBuiltinAnnotation () {
143
164
return factory .getNodeClass ().getAnnotationsByType (Builtin .class )[0 ];
144
165
}
145
166
167
+ @ SuppressWarnings ("StringEquality" )
146
168
@ Override
147
- public boolean equals (Object o ) {
169
+ public final boolean equals (Object o ) {
148
170
if (this == o ) {
149
171
return true ;
150
172
}
151
173
if (o == null || getClass () != o .getClass ()) {
152
174
return false ;
153
175
}
154
176
BuiltinMethodDescriptor that = (BuiltinMethodDescriptor ) o ;
155
- return factory == that .factory && type == that .type ;
177
+ return factory == that .factory && type == that .type && name == that . name ;
156
178
}
157
179
158
180
@ Override
159
- public int hashCode () {
160
- return Objects .hash (factory , type );
181
+ public final int hashCode () {
182
+ return Objects .hash (factory , type , System . identityHashCode ( name ) );
161
183
}
162
184
163
185
// Note: manually written subclass for each builtin works better with Truffle DSL than one
164
186
// generic class that would parametrize the 'factory' field
165
187
166
188
public static final class UnaryBuiltinDescriptor extends BuiltinMethodDescriptor {
167
- public UnaryBuiltinDescriptor (NodeFactory <? extends PythonBuiltinBaseNode > factory , PythonBuiltinClassType type ) {
168
- super (factory , type );
189
+ public UnaryBuiltinDescriptor (String name , NodeFactory <? extends PythonBuiltinBaseNode > factory , PythonBuiltinClassType type ) {
190
+ super (name , factory , type );
169
191
}
170
192
171
193
public PythonUnaryBuiltinNode createNode () {
@@ -174,8 +196,8 @@ public PythonUnaryBuiltinNode createNode() {
174
196
}
175
197
176
198
public static final class BinaryBuiltinDescriptor extends BuiltinMethodDescriptor {
177
- public BinaryBuiltinDescriptor (NodeFactory <? extends PythonBuiltinBaseNode > factory , PythonBuiltinClassType type ) {
178
- super (factory , type );
199
+ public BinaryBuiltinDescriptor (String name , NodeFactory <? extends PythonBuiltinBaseNode > factory , PythonBuiltinClassType type ) {
200
+ super (name , factory , type );
179
201
}
180
202
181
203
public PythonBinaryBuiltinNode createNode () {
@@ -184,8 +206,8 @@ public PythonBinaryBuiltinNode createNode() {
184
206
}
185
207
186
208
public static final class TernaryBuiltinDescriptor extends BuiltinMethodDescriptor {
187
- public TernaryBuiltinDescriptor (NodeFactory <? extends PythonBuiltinBaseNode > factory , PythonBuiltinClassType type ) {
188
- super (factory , type );
209
+ public TernaryBuiltinDescriptor (String name , NodeFactory <? extends PythonBuiltinBaseNode > factory , PythonBuiltinClassType type ) {
210
+ super (name , factory , type );
189
211
}
190
212
191
213
public PythonTernaryBuiltinNode createNode () {
0 commit comments