40
40
*/
41
41
package com .oracle .graal .python .builtins .objects .getsetdescriptor ;
42
42
43
+ import static com .oracle .graal .python .nodes .SpecialMethodNames .__DELETE__ ;
43
44
import static com .oracle .graal .python .nodes .SpecialMethodNames .__GET__ ;
44
45
import static com .oracle .graal .python .nodes .SpecialMethodNames .__REPR__ ;
45
46
import static com .oracle .graal .python .nodes .SpecialMethodNames .__SET__ ;
61
62
import com .oracle .graal .python .builtins .objects .type .TypeNodesFactory .IsSameTypeNodeGen ;
62
63
import com .oracle .graal .python .nodes .ErrorMessages ;
63
64
import com .oracle .graal .python .nodes .PGuards ;
65
+ import com .oracle .graal .python .nodes .PNodeWithContext ;
66
+ import com .oracle .graal .python .nodes .PRaiseNode ;
64
67
import com .oracle .graal .python .nodes .attributes .ReadAttributeFromObjectNode ;
65
68
import com .oracle .graal .python .nodes .attributes .WriteAttributeToObjectNode ;
66
69
import com .oracle .graal .python .nodes .call .special .CallBinaryMethodNode ;
67
70
import com .oracle .graal .python .nodes .call .special .CallUnaryMethodNode ;
68
71
import com .oracle .graal .python .nodes .function .PythonBuiltinBaseNode ;
72
+ import com .oracle .graal .python .nodes .function .builtins .PythonBinaryBuiltinNode ;
69
73
import com .oracle .graal .python .nodes .function .builtins .PythonTernaryBuiltinNode ;
70
74
import com .oracle .graal .python .nodes .function .builtins .PythonUnaryBuiltinNode ;
71
75
import com .oracle .graal .python .nodes .object .GetLazyClassNode ;
@@ -97,20 +101,24 @@ Object repr(GetSetDescriptor descr) {
97
101
}
98
102
}
99
103
100
- abstract static class GetSetNode extends PythonTernaryBuiltinNode {
104
+ abstract static class DescriptorCheckNode extends PNodeWithContext {
101
105
102
106
@ Child private GetMroNode getMroNode ;
103
107
@ Child private GetNameNode getNameNode ;
104
108
@ Child private IsSameTypeNode isSameTypeNode ;
105
109
@ Child private GetLazyClassNode getLazyClassNode ;
110
+ @ Child private PRaiseNode raiseNode ;
106
111
107
112
private final IsBuiltinClassProfile isBuiltinPythonClassObject = IsBuiltinClassProfile .create ();
108
113
private final ConditionProfile isBuiltinProfile = ConditionProfile .createBinaryProfile ();
109
114
private final IsBuiltinClassProfile isBuiltinClassProfile = IsBuiltinClassProfile .create ();
110
115
private final BranchProfile errorBranch = BranchProfile .create ();
111
116
117
+ public abstract boolean execute (LazyPythonClass descrType , String name , Object obj );
118
+
112
119
// https://github.com/python/cpython/blob/e8b19656396381407ad91473af5da8b0d4346e88/Objects/descrobject.c#L70
113
- protected boolean descr_check (LazyPythonClass descrType , String name , Object obj ) {
120
+ @ Specialization
121
+ boolean descr_check (LazyPythonClass descrType , String name , Object obj ) {
114
122
if (PGuards .isNone (obj )) {
115
123
// object's descriptors (__class__,...) need to work on every object including None
116
124
if (!isBuiltinPythonClassObject .profileClass (descrType , PythonBuiltinClassType .PythonObject )) {
@@ -133,7 +141,7 @@ protected boolean descr_check(LazyPythonClass descrType, String name, Object obj
133
141
}
134
142
}
135
143
errorBranch .enter ();
136
- throw raise (TypeError , ErrorMessages .DESC_S_FOR_S_DOESNT_APPLY_TO_S , name , getTypeName (descrType ), getTypeName (type ));
144
+ throw getRaiseNode (). raise (TypeError , ErrorMessages .DESC_S_FOR_S_DOESNT_APPLY_TO_S , name , getTypeName (descrType ), getTypeName (type ));
137
145
}
138
146
139
147
private LazyPythonClass getLazyClass (Object obj ) {
@@ -152,7 +160,7 @@ private PythonAbstractClass[] getMro(LazyPythonClass clazz) {
152
160
return getMroNode .execute (clazz );
153
161
}
154
162
155
- protected Object getTypeName (LazyPythonClass descrType ) {
163
+ private Object getTypeName (LazyPythonClass descrType ) {
156
164
if (getNameNode == null ) {
157
165
CompilerDirectives .transferToInterpreterAndInvalidate ();
158
166
getNameNode = insert (GetNameNode .create ());
@@ -167,18 +175,28 @@ private boolean isSameType(Object left, Object right) {
167
175
}
168
176
return isSameTypeNode .execute (left , right );
169
177
}
178
+
179
+ private PRaiseNode getRaiseNode () {
180
+ if (raiseNode == null ) {
181
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
182
+ raiseNode = insert (PRaiseNode .create ());
183
+ }
184
+ return raiseNode ;
185
+ }
170
186
}
171
187
172
188
@ Builtin (name = __GET__ , minNumOfPositionalArgs = 2 , maxNumOfPositionalArgs = 3 )
173
189
@ GenerateNodeFactory
174
- abstract static class GetSetGetNode extends GetSetNode {
190
+ abstract static class GetSetGetNode extends PythonTernaryBuiltinNode {
191
+ @ Child private GetNameNode getNameNode ;
175
192
private final BranchProfile branchProfile = BranchProfile .create ();
176
193
177
194
// https://github.com/python/cpython/blob/e8b19656396381407ad91473af5da8b0d4346e88/Objects/descrobject.c#L149
178
195
@ Specialization
179
196
Object get (VirtualFrame frame , GetSetDescriptor descr , Object obj , @ SuppressWarnings ("unused" ) Object type ,
197
+ @ Cached DescriptorCheckNode descriptorCheckNode ,
180
198
@ Cached ("create()" ) CallUnaryMethodNode callNode ) {
181
- if (descr_check (descr .getType (), descr .getName (), obj )) {
199
+ if (descriptorCheckNode . execute (descr .getType (), descr .getName (), obj )) {
182
200
return descr ;
183
201
}
184
202
if (descr .getGet () != null ) {
@@ -191,9 +209,10 @@ Object get(VirtualFrame frame, GetSetDescriptor descr, Object obj, @SuppressWarn
191
209
192
210
@ Specialization
193
211
Object getSlot (HiddenKeyDescriptor descr , Object obj , @ SuppressWarnings ("unused" ) Object type ,
212
+ @ Cached DescriptorCheckNode descriptorCheckNode ,
194
213
@ Cached ("create()" ) ReadAttributeFromObjectNode readNode ,
195
214
@ Cached ("createBinaryProfile()" ) ConditionProfile profile ) {
196
- if (descr_check (descr .getType (), descr .getKey ().getName (), obj )) {
215
+ if (descriptorCheckNode . execute (descr .getType (), descr .getKey ().getName (), obj )) {
197
216
return descr ;
198
217
}
199
218
Object val = readNode .execute (obj , descr .getKey ());
@@ -202,17 +221,27 @@ Object getSlot(HiddenKeyDescriptor descr, Object obj, @SuppressWarnings("unused"
202
221
}
203
222
throw raise (AttributeError , descr .getKey ().getName ());
204
223
}
224
+
225
+ private Object getTypeName (LazyPythonClass descrType ) {
226
+ if (getNameNode == null ) {
227
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
228
+ getNameNode = insert (GetNameNode .create ());
229
+ }
230
+ return getNameNode .execute (descrType );
231
+ }
205
232
}
206
233
207
234
@ Builtin (name = __SET__ , minNumOfPositionalArgs = 3 )
208
235
@ GenerateNodeFactory
209
- abstract static class GetSetSetNode extends GetSetNode {
236
+ abstract static class GetSetSetNode extends PythonTernaryBuiltinNode {
237
+ @ Child private GetNameNode getNameNode ;
210
238
private final BranchProfile branchProfile = BranchProfile .create ();
211
239
212
240
@ Specialization
213
241
Object set (VirtualFrame frame , GetSetDescriptor descr , Object obj , Object value ,
242
+ @ Cached DescriptorCheckNode descriptorCheckNode ,
214
243
@ Cached ("create()" ) CallBinaryMethodNode callNode ) {
215
- if (descr_check (descr .getType (), descr .getName (), obj )) {
244
+ if (descriptorCheckNode . execute (descr .getType (), descr .getName (), obj )) {
216
245
return descr ;
217
246
}
218
247
if (descr .getSet () != null ) {
@@ -225,11 +254,65 @@ Object set(VirtualFrame frame, GetSetDescriptor descr, Object obj, Object value,
225
254
226
255
@ Specialization
227
256
Object setSlot (HiddenKeyDescriptor descr , Object obj , Object value ,
257
+ @ Cached DescriptorCheckNode descriptorCheckNode ,
228
258
@ Cached ("create()" ) WriteAttributeToObjectNode writeNode ) {
229
- if (descr_check (descr .getType (), descr .getKey ().getName (), obj )) {
259
+ if (descriptorCheckNode . execute (descr .getType (), descr .getKey ().getName (), obj )) {
230
260
return descr ;
231
261
}
232
262
return writeNode .execute (obj , descr .getKey (), value );
233
263
}
264
+
265
+ private Object getTypeName (LazyPythonClass descrType ) {
266
+ if (getNameNode == null ) {
267
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
268
+ getNameNode = insert (GetNameNode .create ());
269
+ }
270
+ return getNameNode .execute (descrType );
271
+ }
272
+ }
273
+
274
+ @ Builtin (name = __DELETE__ , minNumOfPositionalArgs = 2 )
275
+ @ GenerateNodeFactory
276
+ abstract static class GetSetDeleteNode extends PythonBinaryBuiltinNode {
277
+ @ Child private GetNameNode getNameNode ;
278
+ private final BranchProfile branchProfile = BranchProfile .create ();
279
+
280
+ @ Specialization
281
+ Object delete (VirtualFrame frame , GetSetDescriptor descr , Object obj ,
282
+ @ Cached DescriptorCheckNode descriptorCheckNode ,
283
+ @ Cached ("create()" ) CallBinaryMethodNode callNode ) {
284
+ if (descriptorCheckNode .execute (descr .getType (), descr .getName (), obj )) {
285
+ return descr ;
286
+ }
287
+ if (descr .allowsDelete ()) {
288
+ return callNode .executeObject (frame , descr .getSet (), obj , DescriptorDeleteMarker .INSTANCE );
289
+ } else {
290
+ branchProfile .enter ();
291
+ if (descr .getSet () != null ) {
292
+ throw raise (TypeError , ErrorMessages .CANNOT_DELETE_ATTRIBUTE , getTypeName (descr .getType ()), descr .getName ());
293
+ } else {
294
+ throw raise (AttributeError , ErrorMessages .READONLY_ATTRIBUTE );
295
+ }
296
+ }
297
+ }
298
+
299
+ @ Specialization
300
+ Object deleteSlot (HiddenKeyDescriptor descr , Object obj ,
301
+ @ Cached DescriptorCheckNode descriptorCheckNode ,
302
+ @ Cached ("create()" ) WriteAttributeToObjectNode writeNode ) {
303
+ if (descriptorCheckNode .execute (descr .getType (), descr .getKey ().getName (), obj )) {
304
+ return descr ;
305
+ }
306
+ writeNode .execute (obj , descr .getKey (), PNone .NO_VALUE );
307
+ return PNone .NONE ;
308
+ }
309
+
310
+ private Object getTypeName (LazyPythonClass descrType ) {
311
+ if (getNameNode == null ) {
312
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
313
+ getNameNode = insert (GetNameNode .create ());
314
+ }
315
+ return getNameNode .execute (descrType );
316
+ }
234
317
}
235
318
}
0 commit comments