52
52
import com .oracle .graal .python .builtins .objects .function .PArguments ;
53
53
import com .oracle .graal .python .builtins .objects .function .PKeyword ;
54
54
import com .oracle .graal .python .builtins .objects .str .PString ;
55
+ import com .oracle .graal .python .builtins .objects .superobject .SuperBuiltinsFactory .GetObjectNodeGen ;
56
+ import com .oracle .graal .python .builtins .objects .superobject .SuperBuiltinsFactory .GetObjectTypeNodeGen ;
57
+ import com .oracle .graal .python .builtins .objects .superobject .SuperBuiltinsFactory .GetTypeNodeGen ;
55
58
import com .oracle .graal .python .builtins .objects .superobject .SuperBuiltinsFactory .SuperInitNodeFactory ;
56
59
import com .oracle .graal .python .builtins .objects .type .PythonClass ;
57
60
import com .oracle .graal .python .nodes .SpecialAttributeNames ;
84
87
import com .oracle .truffle .api .frame .FrameSlot ;
85
88
import com .oracle .truffle .api .frame .FrameSlotTypeException ;
86
89
import com .oracle .truffle .api .frame .VirtualFrame ;
90
+ import com .oracle .truffle .api .nodes .Node ;
87
91
import com .oracle .truffle .api .profiles .ConditionProfile ;
88
92
89
93
@ CoreFunctions (extendClasses = PythonBuiltinClassType .Super )
@@ -93,6 +97,54 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
93
97
return SuperBuiltinsFactory .getFactories ();
94
98
}
95
99
100
+ abstract static class GetTypeNode extends Node {
101
+ abstract Object execute (SuperObject self );
102
+
103
+ @ Specialization (guards = "self == cachedSelf" , assumptions = "cachedSelf.getNeverReinitializedAssumption()" , limit = "1" )
104
+ Object cached (@ SuppressWarnings ("unused" ) SuperObject self ,
105
+ @ SuppressWarnings ("unused" ) @ Cached ("self" ) SuperObject cachedSelf ,
106
+ @ Cached ("self.getType()" ) Object type ) {
107
+ return type ;
108
+ }
109
+
110
+ @ Specialization (replaces = "cached" )
111
+ Object uncached (SuperObject self ) {
112
+ return self .getType ();
113
+ }
114
+ }
115
+
116
+ abstract static class GetObjectTypeNode extends Node {
117
+ abstract PythonClass execute (SuperObject self );
118
+
119
+ @ Specialization (guards = "self == cachedSelf" , assumptions = "cachedSelf.getNeverReinitializedAssumption()" , limit = "1" )
120
+ PythonClass cached (@ SuppressWarnings ("unused" ) SuperObject self ,
121
+ @ SuppressWarnings ("unused" ) @ Cached ("self" ) SuperObject cachedSelf ,
122
+ @ Cached ("self.getObjectType()" ) PythonClass type ) {
123
+ return type ;
124
+ }
125
+
126
+ @ Specialization (replaces = "cached" )
127
+ PythonClass uncached (SuperObject self ) {
128
+ return self .getObjectType ();
129
+ }
130
+ }
131
+
132
+ abstract static class GetObjectNode extends Node {
133
+ abstract Object execute (SuperObject self );
134
+
135
+ @ Specialization (guards = "self == cachedSelf" , assumptions = "cachedSelf.getNeverReinitializedAssumption()" , limit = "1" )
136
+ Object cached (@ SuppressWarnings ("unused" ) SuperObject self ,
137
+ @ SuppressWarnings ("unused" ) @ Cached ("self" ) SuperObject cachedSelf ,
138
+ @ Cached ("self.getObject()" ) Object object ) {
139
+ return object ;
140
+ }
141
+
142
+ @ Specialization (replaces = "cached" )
143
+ Object uncached (SuperObject self ) {
144
+ return self .getObject ();
145
+ }
146
+ }
147
+
96
148
@ Builtin (name = SpecialMethodNames .__INIT__ , minNumOfPositionalArgs = 1 , takesVarArgs = true , takesVarKeywordArgs = true , alwaysNeedsCallerFrame = true )
97
149
@ GenerateNodeFactory
98
150
public abstract static class SuperInitNode extends PythonVarargsBuiltinNode {
@@ -307,20 +359,23 @@ private PythonClass supercheck(Object cls, Object object) {
307
359
@ Builtin (name = SpecialMethodNames .__GET__ , fixedNumOfPositionalArgs = 2 , keywordArguments = {"type" })
308
360
@ GenerateNodeFactory
309
361
public abstract static class GetNode extends PythonTernaryBuiltinNode {
362
+ @ Child GetObjectNode getObject = GetObjectNodeGen .create ();
363
+ @ Child GetTypeNode getType ;
310
364
@ Child SuperInitNode superInit ;
311
365
312
366
@ Specialization
313
367
public Object get (SuperObject self , Object obj , @ SuppressWarnings ("unused" ) Object type ) {
314
- if (obj == PNone .NONE || self . getObject ( ) != null ) {
368
+ if (obj == PNone .NONE || getObject . execute ( self ) != null ) {
315
369
// not binding to an object or already bound
316
370
return this ;
317
371
} else {
318
372
if (superInit == null ) {
319
373
CompilerDirectives .transferToInterpreterAndInvalidate ();
320
374
superInit = insert (SuperInitNodeFactory .create ());
375
+ getType = insert (GetTypeNodeGen .create ());
321
376
}
322
377
SuperObject newSuper = factory ().createSuperObject (self .getPythonClass ());
323
- superInit .execute (null , newSuper , self . getType ( ), obj );
378
+ superInit .execute (null , newSuper , getType . execute ( self ), obj );
324
379
return newSuper ;
325
380
}
326
381
}
@@ -331,6 +386,9 @@ public Object get(SuperObject self, Object obj, @SuppressWarnings("unused") Obje
331
386
public abstract static class GetattributeNode extends PythonBinaryBuiltinNode {
332
387
@ Child ReadAttributeFromObjectNode readFromDict = ReadAttributeFromObjectNode .create ();
333
388
@ Child LookupInheritedAttributeNode readGet = LookupInheritedAttributeNode .create (SpecialMethodNames .__GET__ );
389
+ @ Child GetObjectTypeNode getObjectType = GetObjectTypeNodeGen .create ();
390
+ @ Child GetTypeNode getType ;
391
+ @ Child GetObjectNode getObject ;
334
392
@ Child CallTernaryMethodNode callGet ;
335
393
@ Child LookupAndCallBinaryNode getAttr ;
336
394
@@ -342,17 +400,9 @@ private Object genericGetAttr(Object object, Object attr) {
342
400
return getAttr .executeObject (object , attr );
343
401
}
344
402
345
- private CallTernaryMethodNode getCallGet () {
346
- if (callGet == null ) {
347
- CompilerDirectives .transferToInterpreterAndInvalidate ();
348
- callGet = insert (CallTernaryMethodNode .create ());
349
- }
350
- return callGet ;
351
- }
352
-
353
403
@ Specialization
354
404
public Object get (SuperObject self , Object attr ) {
355
- PythonClass startType = self . getObjectType ( );
405
+ PythonClass startType = getObjectType . execute ( self );
356
406
if (startType == null ) {
357
407
return genericGetAttr (self , attr );
358
408
}
@@ -373,12 +423,18 @@ public Object get(SuperObject self, Object attr) {
373
423
}
374
424
}
375
425
426
+ // acts as a branch profile
427
+ if (getType == null ) {
428
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
429
+ getType = insert (GetTypeNodeGen .create ());
430
+ }
431
+
376
432
PythonClass [] mro = startType .getMethodResolutionOrder ();
377
433
/* No need to check the last one: it's gonna be skipped anyway. */
378
434
int i = 0 ;
379
435
int n = mro .length ;
380
436
for (i = 0 ; i + 1 < n ; i ++) {
381
- if (self . getType ( ) == mro [i ]) {
437
+ if (getType . execute ( self ) == mro [i ]) {
382
438
break ;
383
439
}
384
440
}
@@ -396,7 +452,13 @@ public Object get(SuperObject self, Object attr) {
396
452
/*
397
453
* Only pass 'obj' param if this is instance-mode super (See SF ID #743627)
398
454
*/
399
- res = getCallGet ().execute (get , res , self .getObject () == startType ? PNone .NO_VALUE : self .getObject (), startType );
455
+ // acts as a branch profile
456
+ if (getObject == null ) {
457
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
458
+ getObject = insert (GetObjectNodeGen .create ());
459
+ callGet = insert (CallTernaryMethodNode .create ());
460
+ }
461
+ res = callGet .execute (get , res , getObject .execute (self ) == startType ? PNone .NO_VALUE : self .getObject (), startType );
400
462
}
401
463
return res ;
402
464
}
@@ -409,9 +471,11 @@ public Object get(SuperObject self, Object attr) {
409
471
@ Builtin (name = "__thisclass__" , fixedNumOfPositionalArgs = 1 , isGetter = true )
410
472
@ GenerateNodeFactory
411
473
public abstract static class ThisClassNode extends PythonUnaryBuiltinNode {
474
+ @ Child GetTypeNode getType = GetTypeNodeGen .create ();
475
+
412
476
@ Specialization
413
477
Object getClass (SuperObject self ) {
414
- Object type = self . getType ( );
478
+ Object type = getType . execute ( self );
415
479
if (type == null ) {
416
480
return PNone .NONE ;
417
481
}
@@ -422,9 +486,11 @@ Object getClass(SuperObject self) {
422
486
@ Builtin (name = "__self__" , fixedNumOfPositionalArgs = 1 , isGetter = true )
423
487
@ GenerateNodeFactory
424
488
public abstract static class SelfNode extends PythonUnaryBuiltinNode {
489
+ @ Child GetObjectNode getObject = GetObjectNodeGen .create ();
490
+
425
491
@ Specialization
426
492
Object getClass (SuperObject self ) {
427
- Object object = self . getObject ( );
493
+ Object object = getObject . execute ( self );
428
494
if (object == null ) {
429
495
return PNone .NONE ;
430
496
}
@@ -435,9 +501,11 @@ Object getClass(SuperObject self) {
435
501
@ Builtin (name = "__self_class__" , fixedNumOfPositionalArgs = 1 , isGetter = true )
436
502
@ GenerateNodeFactory
437
503
public abstract static class SelfClassNode extends PythonUnaryBuiltinNode {
504
+ @ Child GetObjectTypeNode getObjectType = GetObjectTypeNodeGen .create ();
505
+
438
506
@ Specialization
439
507
Object getClass (SuperObject self ) {
440
- PythonClass objectType = self . getObjectType ( );
508
+ PythonClass objectType = getObjectType . execute ( self );
441
509
if (objectType == null ) {
442
510
return PNone .NONE ;
443
511
}
0 commit comments