1
1
/*
2
- * Copyright (c) 2017, 2019 , Oracle and/or its affiliates. All rights reserved.
2
+ * Copyright (c) 2017, 2020 , Oracle and/or its affiliates. All rights reserved.
3
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
4
*
5
5
* The Universal Permissive License (UPL), Version 1.0
44
44
import static com .oracle .graal .python .nodes .SpecialMethodNames .__GETATTR__ ;
45
45
import static com .oracle .graal .python .runtime .exception .PythonErrorType .AttributeError ;
46
46
47
+ import com .oracle .graal .python .builtins .objects .PNone ;
47
48
import com .oracle .graal .python .nodes .attributes .GetAttributeNodeGen .GetAnyAttributeNodeGen ;
48
49
import com .oracle .graal .python .nodes .attributes .GetAttributeNodeGen .GetFixedAttributeNodeGen ;
50
+ import com .oracle .graal .python .nodes .call .special .CallBinaryMethodNode ;
49
51
import com .oracle .graal .python .nodes .call .special .LookupAndCallBinaryNode ;
50
52
import com .oracle .graal .python .nodes .expression .ExpressionNode ;
51
53
import com .oracle .graal .python .nodes .frame .ReadNode ;
59
61
import com .oracle .truffle .api .frame .VirtualFrame ;
60
62
import com .oracle .truffle .api .nodes .Node ;
61
63
import com .oracle .truffle .api .nodes .UnexpectedResultException ;
64
+ import com .oracle .truffle .api .profiles .ConditionProfile ;
62
65
63
66
@ NodeChild (value = "object" , type = ExpressionNode .class )
64
67
public abstract class GetAttributeNode extends ExpressionNode implements ReadNode {
@@ -108,12 +111,68 @@ public final StatementNode makeWriteNode(ExpressionNode rhs) {
108
111
109
112
public abstract ExpressionNode getObject ();
110
113
111
- public abstract static class GetFixedAttributeNode extends Node {
114
+ abstract static class GetAttributeBaseNode extends Node {
115
+
116
+ @ Child private LookupInheritedAttributeNode lookupGetattrNode ;
117
+ @ Child private CallBinaryMethodNode callBinaryMethodNode ;
118
+
119
+ @ CompilationFinal private ConditionProfile hasGetattrProfile ;
120
+
121
+ int dispatchGetAttrOrRethrowInt (VirtualFrame frame , Object object , Object key , PException pe ) throws UnexpectedResultException {
122
+ return ensureCallGetattrNode ().executeInt (frame , lookupGetattrOrRethrow (object , pe ), object , key );
123
+ }
124
+
125
+ long dispatchGetAttrOrRethrowLong (VirtualFrame frame , Object object , Object key , PException pe ) throws UnexpectedResultException {
126
+ return ensureCallGetattrNode ().executeLong (frame , lookupGetattrOrRethrow (object , pe ), object , key );
127
+ }
128
+
129
+ boolean dispatchGetAttrOrRethrowBool (VirtualFrame frame , Object object , Object key , PException pe ) throws UnexpectedResultException {
130
+ return ensureCallGetattrNode ().executeBool (frame , lookupGetattrOrRethrow (object , pe ), object , key );
131
+ }
132
+
133
+ Object dispatchGetAttrOrRethrowObject (VirtualFrame frame , Object object , Object key , PException pe ) {
134
+ return ensureCallGetattrNode ().executeObject (frame , lookupGetattrOrRethrow (object , pe ), object , key );
135
+ }
136
+
137
+ /** Lookup {@code __getattr__} or rethrow {@code pe} if it does not exist. */
138
+ private Object lookupGetattrOrRethrow (Object object , PException pe ) {
139
+ Object getattrAttribute = ensureLookupGetattrNode ().execute (object );
140
+ if (ensureHasGetattrProfile ().profile (getattrAttribute == PNone .NO_VALUE )) {
141
+ throw pe ;
142
+ }
143
+ return getattrAttribute ;
144
+ }
145
+
146
+ private LookupInheritedAttributeNode ensureLookupGetattrNode () {
147
+ if (lookupGetattrNode == null ) {
148
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
149
+ lookupGetattrNode = insert (LookupInheritedAttributeNode .create (__GETATTR__ ));
150
+ }
151
+ return lookupGetattrNode ;
152
+ }
153
+
154
+ private CallBinaryMethodNode ensureCallGetattrNode () {
155
+ if (callBinaryMethodNode == null ) {
156
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
157
+ callBinaryMethodNode = insert (CallBinaryMethodNode .create ());
158
+ }
159
+ return callBinaryMethodNode ;
160
+ }
161
+
162
+ private ConditionProfile ensureHasGetattrProfile () {
163
+ if (hasGetattrProfile == null ) {
164
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
165
+ hasGetattrProfile = ConditionProfile .createBinaryProfile ();
166
+ }
167
+ return hasGetattrProfile ;
168
+ }
169
+ }
170
+
171
+ public abstract static class GetFixedAttributeNode extends GetAttributeBaseNode {
112
172
113
173
private final String key ;
114
174
115
175
@ Child private LookupAndCallBinaryNode dispatchNode = LookupAndCallBinaryNode .create (__GETATTRIBUTE__ );
116
- @ Child private LookupAndCallBinaryNode dispatchGetAttr ;
117
176
@ CompilationFinal private IsBuiltinClassProfile isBuiltinClassProfile = IsBuiltinClassProfile .create ();
118
177
119
178
public GetFixedAttributeNode (String key ) {
@@ -138,7 +197,7 @@ protected int doItInt(VirtualFrame frame, Object object) throws UnexpectedResult
138
197
return dispatchNode .executeInt (frame , object , key );
139
198
} catch (PException pe ) {
140
199
pe .expect (AttributeError , isBuiltinClassProfile );
141
- return getDispatchGetAttr (). executeInt ( frame , object , key );
200
+ return dispatchGetAttrOrRethrowInt ( frame , object , key , pe );
142
201
}
143
202
}
144
203
@@ -148,7 +207,7 @@ protected long doItLong(VirtualFrame frame, Object object) throws UnexpectedResu
148
207
return dispatchNode .executeLong (frame , object , key );
149
208
} catch (PException pe ) {
150
209
pe .expect (AttributeError , isBuiltinClassProfile );
151
- return getDispatchGetAttr (). executeInt ( frame , object , key );
210
+ return dispatchGetAttrOrRethrowLong ( frame , object , key , pe );
152
211
}
153
212
}
154
213
@@ -158,7 +217,7 @@ protected boolean doItBoolean(VirtualFrame frame, Object object) throws Unexpect
158
217
return dispatchNode .executeBool (frame , object , key );
159
218
} catch (PException pe ) {
160
219
pe .expect (AttributeError , isBuiltinClassProfile );
161
- return getDispatchGetAttr (). executeBool ( frame , object , key );
220
+ return dispatchGetAttrOrRethrowBool ( frame , object , key , pe );
162
221
}
163
222
}
164
223
@@ -168,27 +227,18 @@ protected Object doIt(VirtualFrame frame, Object object) {
168
227
return dispatchNode .executeObject (frame , object , key );
169
228
} catch (PException pe ) {
170
229
pe .expect (AttributeError , isBuiltinClassProfile );
171
- return getDispatchGetAttr (). executeObject ( frame , object , key );
230
+ return dispatchGetAttrOrRethrowObject ( frame , object , key , pe );
172
231
}
173
232
}
174
233
175
- private LookupAndCallBinaryNode getDispatchGetAttr () {
176
- if (dispatchGetAttr == null ) {
177
- CompilerDirectives .transferToInterpreterAndInvalidate ();
178
- dispatchGetAttr = insert (LookupAndCallBinaryNode .create (__GETATTR__ ));
179
- }
180
- return dispatchGetAttr ;
181
- }
182
-
183
234
public static GetFixedAttributeNode create (String key ) {
184
235
return GetFixedAttributeNodeGen .create (key );
185
236
}
186
237
}
187
238
188
- public abstract static class GetAnyAttributeNode extends Node {
239
+ public abstract static class GetAnyAttributeNode extends GetAttributeBaseNode {
189
240
190
241
@ Child private LookupAndCallBinaryNode dispatchNode = LookupAndCallBinaryNode .create (__GETATTRIBUTE__ );
191
- @ Child private LookupAndCallBinaryNode dispatchGetAttr ;
192
242
@ CompilationFinal private IsBuiltinClassProfile isBuiltinClassProfile = IsBuiltinClassProfile .create ();
193
243
194
244
public abstract int executeInt (VirtualFrame frame , Object object , Object key ) throws UnexpectedResultException ;
@@ -205,7 +255,7 @@ protected int doItInt(VirtualFrame frame, Object object, String key) throws Unex
205
255
return dispatchNode .executeInt (frame , object , key );
206
256
} catch (PException pe ) {
207
257
pe .expect (AttributeError , isBuiltinClassProfile );
208
- return getDispatchGetAttr (). executeInt ( frame , object , key );
258
+ return dispatchGetAttrOrRethrowInt ( frame , object , key , pe );
209
259
}
210
260
}
211
261
@@ -215,7 +265,7 @@ protected long doItLong(VirtualFrame frame, Object object, Object key) throws Un
215
265
return dispatchNode .executeLong (frame , object , key );
216
266
} catch (PException pe ) {
217
267
pe .expect (AttributeError , isBuiltinClassProfile );
218
- return getDispatchGetAttr (). executeInt ( frame , object , key );
268
+ return dispatchGetAttrOrRethrowLong ( frame , object , key , pe );
219
269
}
220
270
}
221
271
@@ -225,7 +275,7 @@ protected boolean doItBoolean(VirtualFrame frame, Object object, Object key) thr
225
275
return dispatchNode .executeBool (frame , object , key );
226
276
} catch (PException pe ) {
227
277
pe .expect (AttributeError , isBuiltinClassProfile );
228
- return getDispatchGetAttr (). executeBool ( frame , object , key );
278
+ return dispatchGetAttrOrRethrowBool ( frame , object , key , pe );
229
279
}
230
280
}
231
281
@@ -235,16 +285,8 @@ protected Object doIt(VirtualFrame frame, Object object, Object key) {
235
285
return dispatchNode .executeObject (frame , object , key );
236
286
} catch (PException pe ) {
237
287
pe .expect (AttributeError , isBuiltinClassProfile );
238
- return getDispatchGetAttr ().executeObject (frame , object , key );
239
- }
240
- }
241
-
242
- private LookupAndCallBinaryNode getDispatchGetAttr () {
243
- if (dispatchGetAttr == null ) {
244
- CompilerDirectives .transferToInterpreterAndInvalidate ();
245
- dispatchGetAttr = insert (LookupAndCallBinaryNode .create (__GETATTR__ ));
288
+ return dispatchGetAttrOrRethrowObject (frame , object , key , pe );
246
289
}
247
- return dispatchGetAttr ;
248
290
}
249
291
250
292
public static GetAnyAttributeNode create () {
0 commit comments