Skip to content

Commit 1a471a7

Browse files
committed
Do not reference run-time objects in HPy ext root nodes
1 parent 706427f commit 1a471a7

File tree

1 file changed

+58
-37
lines changed

1 file changed

+58
-37
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/HPyExternalFunctionNodes.java

Lines changed: 58 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@
4545
import com.oracle.graal.python.PythonLanguage;
4646
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
4747
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;
4850
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyDef.HPyFuncSignature;
4951
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyAsPythonObjectNode;
5052
import com.oracle.graal.python.builtins.objects.cext.hpy.GraalHPyNodes.HPyCloseArgHandlesNode;
@@ -105,6 +107,18 @@
105107

106108
public abstract class HPyExternalFunctionNodes {
107109

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+
108122
/**
109123
* Creates a built-in function that accepts the specified signatures, does appropriate argument
110124
* and result conversion and calls the provided callable.
@@ -119,6 +133,7 @@ public abstract class HPyExternalFunctionNodes {
119133
*/
120134
@TruffleBoundary
121135
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";
122137
PRootNode rootNode;
123138
int numDefaults = 0;
124139
switch (signature) {
@@ -128,41 +143,42 @@ static PBuiltinFunction createWrapperFunction(PythonLanguage language, HPyFuncSi
128143
case GETITERFUNC:
129144
case ITERNEXTFUNC:
130145
case DESTROYFUNC:
131-
rootNode = new HPyMethNoargsRoot(language, name, callable, false);
146+
rootNode = new HPyMethNoargsRoot(language, name, false);
132147
break;
133148
case O:
134149
case BINARYFUNC:
135-
rootNode = new HPyMethORoot(language, name, callable, false);
150+
rootNode = new HPyMethORoot(language, name, false);
136151
break;
137152
case KEYWORDS:
138-
rootNode = new HPyMethKeywordsRoot(language, name, callable);
153+
rootNode = new HPyMethKeywordsRoot(language, name);
139154
break;
140155
case INITPROC:
141-
rootNode = new HPyMethInitProcRoot(language, name, callable);
156+
rootNode = new HPyMethInitProcRoot(language, name);
142157
break;
143158
case VARARGS:
144-
rootNode = new HPyMethVarargsRoot(language, name, callable);
159+
rootNode = new HPyMethVarargsRoot(language, name);
145160
break;
146161
case TERNARYFUNC:
147-
rootNode = new HPyMethTernaryRoot(language, name, callable);
162+
rootNode = new HPyMethTernaryRoot(language, name);
148163
// the third argument is optional
149164
// so it has a default value (this implicitly is 'None')
150165
numDefaults = 1;
151166
break;
152167
case LENFUNC:
153-
rootNode = new HPyMethNoargsRoot(language, name, callable, true);
168+
rootNode = new HPyMethNoargsRoot(language, name, true);
154169
break;
155170
case INQUIRY:
156-
rootNode = new HPyMethInquiryRoot(language, name, callable);
171+
rootNode = new HPyMethInquiryRoot(language, name);
157172
break;
158173
case SSIZEARGFUNC:
159-
rootNode = new HPyMethSSizeArgFuncRoot(language, name, callable);
174+
rootNode = new HPyMethSSizeArgFuncRoot(language, name);
160175
break;
161176
default:
162177
// TODO(fa): support remaining signatures
163178
throw CompilerDirectives.shouldNotReachHere("unsupported HPy method signature: " + signature.name());
164179
}
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));
166182
}
167183

168184
/**
@@ -257,34 +273,31 @@ abstract static class HPyMethodDescriptorRootNode extends PRootNode {
257273
@Child private CalleeContext calleeContext;
258274
@Child private HPyExternalFunctionInvokeNode invokeNode;
259275
@Child private ReadIndexedArgumentNode readSelfNode;
276+
@Child private CellBuiltins.GetRefNode readTargetCellNode;
260277

261278
private final String name;
262-
private final Object callable;
263279

264280
@TruffleBoundary
265-
public HPyMethodDescriptorRootNode(PythonLanguage language, String name, Object callable, HPyConvertArgsToSulongNode convertArgsToSulongNode) {
281+
public HPyMethodDescriptorRootNode(PythonLanguage language, String name, HPyConvertArgsToSulongNode convertArgsToSulongNode) {
266282
super(language);
267-
assert InteropLibrary.getUncached(callable).isExecutable(callable) : "object is not callable";
268283
this.name = name;
269-
this.callable = callable;
270284
this.invokeNode = HPyExternalFunctionInvokeNodeGen.create(convertArgsToSulongNode);
271285
}
272286

273287
@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) {
277289
super(language);
278-
assert InteropLibrary.getUncached(callable).isExecutable(callable) : "object is not callable";
279290
this.name = name;
280-
this.callable = callable;
281291
this.invokeNode = HPyExternalFunctionInvokeNodeGen.create(checkFunctionResultNode, convertArgsToSulongNode);
282292
}
283293

284294
@Override
285295
public Object execute(VirtualFrame frame) {
286296
getCalleeContext().enter(frame);
287297
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]);
288301
return processResult(frame, invokeNode.execute(frame, name, callable, prepareCArguments(frame)));
289302
} finally {
290303
getCalleeContext().exit(frame, this);
@@ -313,6 +326,14 @@ private CalleeContext getCalleeContext() {
313326
return calleeContext;
314327
}
315328

329+
private CellBuiltins.GetRefNode ensureReadTargetCellNode() {
330+
if (readTargetCellNode == null) {
331+
CompilerDirectives.transferToInterpreterAndInvalidate();
332+
readTargetCellNode = insert(CellBuiltins.GetRefNode.create());
333+
}
334+
return readTargetCellNode;
335+
}
336+
316337
@Override
317338
public boolean isCloningAllowed() {
318339
return true;
@@ -343,8 +364,8 @@ public boolean isPythonInternal() {
343364
static final class HPyMethNoargsRoot extends HPyMethodDescriptorRootNode {
344365
private static final Signature SIGNATURE = new Signature(1, false, -1, false, new String[]{"self"}, EMPTY_STRING_ARRAY, true);
345366

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());
348369
}
349370

350371
@Override
@@ -363,8 +384,8 @@ static final class HPyMethORoot extends HPyMethodDescriptorRootNode {
363384

364385
@Child private ReadIndexedArgumentNode readArgNode;
365386

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());
368389
}
369390

370391
@Override
@@ -392,8 +413,8 @@ static final class HPyMethVarargsRoot extends HPyMethodDescriptorRootNode {
392413
@Child private ReadVarArgsNode readVarargsNode;
393414

394415
@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());
397418
}
398419

399420
@Override
@@ -423,8 +444,8 @@ static final class HPyMethKeywordsRoot extends HPyMethodDescriptorRootNode {
423444
@Child private ReadVarKeywordsNode readKwargsNode;
424445

425446
@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());
428449
}
429450

430451
@Override
@@ -462,8 +483,8 @@ static final class HPyMethInitProcRoot extends HPyMethodDescriptorRootNode {
462483
@Child private ReadVarKeywordsNode readKwargsNode;
463484

464485
@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());
467488
}
468489

469490
@Override
@@ -508,8 +529,8 @@ static final class HPyMethTernaryRoot extends HPyMethodDescriptorRootNode {
508529
@Child private ReadIndexedArgumentNode readArg1Node;
509530
@Child private ReadIndexedArgumentNode readArg2Node;
510531

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());
513534
}
514535

515536
@Override
@@ -545,8 +566,8 @@ static final class HPyMethSSizeArgFuncRoot extends HPyMethodDescriptorRootNode {
545566

546567
@Child private ReadIndexedArgumentNode readArg1Node;
547568

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());
550571
}
551572

552573
@Override
@@ -574,8 +595,8 @@ static final class HPyMethSSizeSSizeArgFuncRoot extends HPyMethodDescriptorRootN
574595
@Child private ReadIndexedArgumentNode readArg1Node;
575596
@Child private ReadIndexedArgumentNode readArg2Node;
576597

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());
579600
}
580601

581602
@Override
@@ -613,8 +634,8 @@ static final class HPyMethInquiryRoot extends HPyMethodDescriptorRootNode {
613634

614635
@Child private CastToJavaIntExactNode castToJavaIntExactNode;
615636

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());
618639
}
619640

620641
@Override

0 commit comments

Comments
 (0)