45
45
import com .oracle .graal .python .PythonLanguage ;
46
46
import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
47
47
import com .oracle .graal .python .builtins .objects .PNone ;
48
+ import com .oracle .graal .python .builtins .objects .cell .CellBuiltins ;
49
+ import com .oracle .graal .python .builtins .objects .cell .PCell ;
48
50
import com .oracle .graal .python .builtins .objects .cext .hpy .GraalHPyDef .HPyFuncSignature ;
49
51
import com .oracle .graal .python .builtins .objects .cext .hpy .GraalHPyNodes .HPyAsPythonObjectNode ;
50
52
import com .oracle .graal .python .builtins .objects .cext .hpy .GraalHPyNodes .HPyCloseArgHandlesNode ;
105
107
106
108
public abstract class HPyExternalFunctionNodes {
107
109
110
+ /**
111
+ * The index of the cell that contains the target (e.g. the pointer of native getter/setter
112
+ * function).
113
+ */
114
+ private static final int CELL_INDEX_TARGET = 0 ;
115
+
116
+ private static PCell [] createPythonClosure (Object target , PythonObjectFactory factory , Assumption effectivelyFinal ) {
117
+ PCell targetCell = factory .createCell (effectivelyFinal );
118
+ targetCell .setRef (target );
119
+ return new PCell []{targetCell };
120
+ }
121
+
108
122
/**
109
123
* Creates a built-in function that accepts the specified signatures, does appropriate argument
110
124
* and result conversion and calls the provided callable.
@@ -119,6 +133,7 @@ public abstract class HPyExternalFunctionNodes {
119
133
*/
120
134
@ TruffleBoundary
121
135
static PBuiltinFunction createWrapperFunction (PythonLanguage language , HPyFuncSignature signature , String name , Object callable , Object enclosingType , PythonObjectFactory factory ) {
136
+ assert InteropLibrary .getUncached (callable ).isExecutable (callable ) : "object is not callable" ;
122
137
PRootNode rootNode ;
123
138
int numDefaults = 0 ;
124
139
switch (signature ) {
@@ -128,41 +143,42 @@ static PBuiltinFunction createWrapperFunction(PythonLanguage language, HPyFuncSi
128
143
case GETITERFUNC :
129
144
case ITERNEXTFUNC :
130
145
case DESTROYFUNC :
131
- rootNode = new HPyMethNoargsRoot (language , name , callable , false );
146
+ rootNode = new HPyMethNoargsRoot (language , name , false );
132
147
break ;
133
148
case O :
134
149
case BINARYFUNC :
135
- rootNode = new HPyMethORoot (language , name , callable , false );
150
+ rootNode = new HPyMethORoot (language , name , false );
136
151
break ;
137
152
case KEYWORDS :
138
- rootNode = new HPyMethKeywordsRoot (language , name , callable );
153
+ rootNode = new HPyMethKeywordsRoot (language , name );
139
154
break ;
140
155
case INITPROC :
141
- rootNode = new HPyMethInitProcRoot (language , name , callable );
156
+ rootNode = new HPyMethInitProcRoot (language , name );
142
157
break ;
143
158
case VARARGS :
144
- rootNode = new HPyMethVarargsRoot (language , name , callable );
159
+ rootNode = new HPyMethVarargsRoot (language , name );
145
160
break ;
146
161
case TERNARYFUNC :
147
- rootNode = new HPyMethTernaryRoot (language , name , callable );
162
+ rootNode = new HPyMethTernaryRoot (language , name );
148
163
// the third argument is optional
149
164
// so it has a default value (this implicitly is 'None')
150
165
numDefaults = 1 ;
151
166
break ;
152
167
case LENFUNC :
153
- rootNode = new HPyMethNoargsRoot (language , name , callable , true );
168
+ rootNode = new HPyMethNoargsRoot (language , name , true );
154
169
break ;
155
170
case INQUIRY :
156
- rootNode = new HPyMethInquiryRoot (language , name , callable );
171
+ rootNode = new HPyMethInquiryRoot (language , name );
157
172
break ;
158
173
case SSIZEARGFUNC :
159
- rootNode = new HPyMethSSizeArgFuncRoot (language , name , callable );
174
+ rootNode = new HPyMethSSizeArgFuncRoot (language , name );
160
175
break ;
161
176
default :
162
177
// TODO(fa): support remaining signatures
163
178
throw CompilerDirectives .shouldNotReachHere ("unsupported HPy method signature: " + signature .name ());
164
179
}
165
- return factory .createBuiltinFunction (name , enclosingType , numDefaults , PythonUtils .getOrCreateCallTarget (rootNode ));
180
+ PCell [] closure = createPythonClosure (callable , factory , language .getCallableStableAssumption ());
181
+ return factory .createBuiltinFunction (name , enclosingType , numDefaults , closure , PythonUtils .getOrCreateCallTarget (rootNode ));
166
182
}
167
183
168
184
/**
@@ -257,34 +273,31 @@ abstract static class HPyMethodDescriptorRootNode extends PRootNode {
257
273
@ Child private CalleeContext calleeContext ;
258
274
@ Child private HPyExternalFunctionInvokeNode invokeNode ;
259
275
@ Child private ReadIndexedArgumentNode readSelfNode ;
276
+ @ Child private CellBuiltins .GetRefNode readTargetCellNode ;
260
277
261
278
private final String name ;
262
- private final Object callable ;
263
279
264
280
@ TruffleBoundary
265
- public HPyMethodDescriptorRootNode (PythonLanguage language , String name , Object callable , HPyConvertArgsToSulongNode convertArgsToSulongNode ) {
281
+ public HPyMethodDescriptorRootNode (PythonLanguage language , String name , HPyConvertArgsToSulongNode convertArgsToSulongNode ) {
266
282
super (language );
267
- assert InteropLibrary .getUncached (callable ).isExecutable (callable ) : "object is not callable" ;
268
283
this .name = name ;
269
- this .callable = callable ;
270
284
this .invokeNode = HPyExternalFunctionInvokeNodeGen .create (convertArgsToSulongNode );
271
285
}
272
286
273
287
@ TruffleBoundary
274
- public HPyMethodDescriptorRootNode (PythonLanguage language , String name , Object callable ,
275
- HPyCheckFunctionResultNode checkFunctionResultNode ,
276
- HPyConvertArgsToSulongNode convertArgsToSulongNode ) {
288
+ public HPyMethodDescriptorRootNode (PythonLanguage language , String name , HPyCheckFunctionResultNode checkFunctionResultNode , HPyConvertArgsToSulongNode convertArgsToSulongNode ) {
277
289
super (language );
278
- assert InteropLibrary .getUncached (callable ).isExecutable (callable ) : "object is not callable" ;
279
290
this .name = name ;
280
- this .callable = callable ;
281
291
this .invokeNode = HPyExternalFunctionInvokeNodeGen .create (checkFunctionResultNode , convertArgsToSulongNode );
282
292
}
283
293
284
294
@ Override
285
295
public Object execute (VirtualFrame frame ) {
286
296
getCalleeContext ().enter (frame );
287
297
try {
298
+ PCell [] frameClosure = PArguments .getClosure (frame );
299
+ assert frameClosure .length == 1 : "invalid closure for HPyMethodDescriptorRootNode" ;
300
+ Object callable = ensureReadTargetCellNode ().execute (frameClosure [CELL_INDEX_TARGET ]);
288
301
return processResult (frame , invokeNode .execute (frame , name , callable , prepareCArguments (frame )));
289
302
} finally {
290
303
getCalleeContext ().exit (frame , this );
@@ -313,6 +326,14 @@ private CalleeContext getCalleeContext() {
313
326
return calleeContext ;
314
327
}
315
328
329
+ private CellBuiltins .GetRefNode ensureReadTargetCellNode () {
330
+ if (readTargetCellNode == null ) {
331
+ CompilerDirectives .transferToInterpreterAndInvalidate ();
332
+ readTargetCellNode = insert (CellBuiltins .GetRefNode .create ());
333
+ }
334
+ return readTargetCellNode ;
335
+ }
336
+
316
337
@ Override
317
338
public boolean isCloningAllowed () {
318
339
return true ;
@@ -343,8 +364,8 @@ public boolean isPythonInternal() {
343
364
static final class HPyMethNoargsRoot extends HPyMethodDescriptorRootNode {
344
365
private static final Signature SIGNATURE = new Signature (1 , false , -1 , false , new String []{"self" }, EMPTY_STRING_ARRAY , true );
345
366
346
- public HPyMethNoargsRoot (PythonLanguage language , String name , Object callable , boolean nativePrimitiveResult ) {
347
- super (language , name , callable , nativePrimitiveResult ? HPyCheckPrimitiveResultNodeGen .create () : HPyCheckHandleResultNodeGen .create (), HPyAllAsHandleNodeGen .create ());
367
+ public HPyMethNoargsRoot (PythonLanguage language , String name , boolean nativePrimitiveResult ) {
368
+ super (language , name , nativePrimitiveResult ? HPyCheckPrimitiveResultNodeGen .create () : HPyCheckHandleResultNodeGen .create (), HPyAllAsHandleNodeGen .create ());
348
369
}
349
370
350
371
@ Override
@@ -363,8 +384,8 @@ static final class HPyMethORoot extends HPyMethodDescriptorRootNode {
363
384
364
385
@ Child private ReadIndexedArgumentNode readArgNode ;
365
386
366
- public HPyMethORoot (PythonLanguage language , String name , Object callable , boolean nativePrimitiveResult ) {
367
- super (language , name , callable , nativePrimitiveResult ? HPyCheckPrimitiveResultNodeGen .create () : HPyCheckHandleResultNodeGen .create (), HPyAllAsHandleNodeGen .create ());
387
+ public HPyMethORoot (PythonLanguage language , String name , boolean nativePrimitiveResult ) {
388
+ super (language , name , nativePrimitiveResult ? HPyCheckPrimitiveResultNodeGen .create () : HPyCheckHandleResultNodeGen .create (), HPyAllAsHandleNodeGen .create ());
368
389
}
369
390
370
391
@ Override
@@ -392,8 +413,8 @@ static final class HPyMethVarargsRoot extends HPyMethodDescriptorRootNode {
392
413
@ Child private ReadVarArgsNode readVarargsNode ;
393
414
394
415
@ TruffleBoundary
395
- public HPyMethVarargsRoot (PythonLanguage language , String name , Object callable ) {
396
- super (language , name , callable , HPyVarargsToSulongNodeGen .create ());
416
+ public HPyMethVarargsRoot (PythonLanguage language , String name ) {
417
+ super (language , name , HPyVarargsToSulongNodeGen .create ());
397
418
}
398
419
399
420
@ Override
@@ -423,8 +444,8 @@ static final class HPyMethKeywordsRoot extends HPyMethodDescriptorRootNode {
423
444
@ Child private ReadVarKeywordsNode readKwargsNode ;
424
445
425
446
@ TruffleBoundary
426
- public HPyMethKeywordsRoot (PythonLanguage language , String name , Object callable ) {
427
- super (language , name , callable , HPyKeywordsToSulongNodeGen .create ());
447
+ public HPyMethKeywordsRoot (PythonLanguage language , String name ) {
448
+ super (language , name , HPyKeywordsToSulongNodeGen .create ());
428
449
}
429
450
430
451
@ Override
@@ -462,8 +483,8 @@ static final class HPyMethInitProcRoot extends HPyMethodDescriptorRootNode {
462
483
@ Child private ReadVarKeywordsNode readKwargsNode ;
463
484
464
485
@ TruffleBoundary
465
- public HPyMethInitProcRoot (PythonLanguage language , String name , Object callable ) {
466
- super (language , name , callable , HPyCheckPrimitiveResultNodeGen .create (), HPyKeywordsToSulongNodeGen .create ());
486
+ public HPyMethInitProcRoot (PythonLanguage language , String name ) {
487
+ super (language , name , HPyCheckPrimitiveResultNodeGen .create (), HPyKeywordsToSulongNodeGen .create ());
467
488
}
468
489
469
490
@ Override
@@ -508,8 +529,8 @@ static final class HPyMethTernaryRoot extends HPyMethodDescriptorRootNode {
508
529
@ Child private ReadIndexedArgumentNode readArg1Node ;
509
530
@ Child private ReadIndexedArgumentNode readArg2Node ;
510
531
511
- public HPyMethTernaryRoot (PythonLanguage language , String name , Object callable ) {
512
- super (language , name , callable , HPyAllAsHandleNodeGen .create ());
532
+ public HPyMethTernaryRoot (PythonLanguage language , String name ) {
533
+ super (language , name , HPyAllAsHandleNodeGen .create ());
513
534
}
514
535
515
536
@ Override
@@ -545,8 +566,8 @@ static final class HPyMethSSizeArgFuncRoot extends HPyMethodDescriptorRootNode {
545
566
546
567
@ Child private ReadIndexedArgumentNode readArg1Node ;
547
568
548
- public HPyMethSSizeArgFuncRoot (PythonLanguage language , String name , Object callable ) {
549
- super (language , name , callable , HPySSizeArgFuncToSulongNodeGen .create ());
569
+ public HPyMethSSizeArgFuncRoot (PythonLanguage language , String name ) {
570
+ super (language , name , HPySSizeArgFuncToSulongNodeGen .create ());
550
571
}
551
572
552
573
@ Override
@@ -574,8 +595,8 @@ static final class HPyMethSSizeSSizeArgFuncRoot extends HPyMethodDescriptorRootN
574
595
@ Child private ReadIndexedArgumentNode readArg1Node ;
575
596
@ Child private ReadIndexedArgumentNode readArg2Node ;
576
597
577
- public HPyMethSSizeSSizeArgFuncRoot (PythonLanguage language , String name , Object callable ) {
578
- super (language , name , callable , HPySSizeArgFuncToSulongNodeGen .create ());
598
+ public HPyMethSSizeSSizeArgFuncRoot (PythonLanguage language , String name ) {
599
+ super (language , name , HPySSizeArgFuncToSulongNodeGen .create ());
579
600
}
580
601
581
602
@ Override
@@ -613,8 +634,8 @@ static final class HPyMethInquiryRoot extends HPyMethodDescriptorRootNode {
613
634
614
635
@ Child private CastToJavaIntExactNode castToJavaIntExactNode ;
615
636
616
- public HPyMethInquiryRoot (PythonLanguage language , String name , Object callable ) {
617
- super (language , name , callable , HPyCheckPrimitiveResultNodeGen .create (), HPyAllAsHandleNodeGen .create ());
637
+ public HPyMethInquiryRoot (PythonLanguage language , String name ) {
638
+ super (language , name , HPyCheckPrimitiveResultNodeGen .create (), HPyAllAsHandleNodeGen .create ());
618
639
}
619
640
620
641
@ Override
0 commit comments