Skip to content

Commit dae0482

Browse files
committed
Use default values instead of closure
1 parent 03f1c3a commit dae0482

File tree

11 files changed

+86
-148
lines changed

11 files changed

+86
-148
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -184,12 +184,6 @@ public final class PythonLanguage extends TruffleLanguage<PythonContext> {
184184
@CompilationFinal(dimensions = 1) private volatile Object[] engineOptionsStorage;
185185
@CompilationFinal private volatile OptionValues engineOptions;
186186

187-
/**
188-
* A shared assumption that indicates that the delegate of a built-in function that decorates a
189-
* native member method or similar did not change.
190-
*/
191-
@CompilationFinal private Assumption callableStableAssumption;
192-
193187
public static int getNumberOfSpecialSingletons() {
194188
return CONTEXT_INSENSITIVE_SINGLETONS.length;
195189
}
@@ -773,12 +767,4 @@ private RootCallTarget getOrCreateArithmeticCallTarget(Object arithmeticOperator
773767
assert callTarget != null;
774768
return callTarget;
775769
}
776-
777-
public Assumption getCallableStableAssumption() {
778-
if (callableStableAssumption == null) {
779-
CompilerDirectives.transferToInterpreterAndInvalidate();
780-
callableStableAssumption = Truffle.getRuntime().createAssumption("method descriptor delegate stable assumption");
781-
}
782-
return callableStableAssumption;
783-
}
784770
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ExternalFunctionNodes.java

Lines changed: 30 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,6 @@
4949
import com.oracle.graal.python.builtins.modules.PythonCextBuiltins.PExternalFunctionWrapper;
5050
import com.oracle.graal.python.builtins.modules.PythonCextBuiltinsFactory.DefaultCheckFunctionResultNodeGen;
5151
import com.oracle.graal.python.builtins.objects.PNone;
52-
import com.oracle.graal.python.builtins.objects.cell.CellBuiltins;
53-
import com.oracle.graal.python.builtins.objects.cell.CellBuiltins.GetRefNode;
54-
import com.oracle.graal.python.builtins.objects.cell.PCell;
5552
import com.oracle.graal.python.builtins.objects.cext.capi.CApiGuards;
5653
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes;
5754
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.ConvertArgsToSulongNode;
@@ -117,24 +114,16 @@
117114

118115
public abstract class ExternalFunctionNodes {
119116

120-
/**
121-
* The index of the cell that contains the target (e.g. the pointer of native getter/setter
122-
* function).
123-
*/
124-
static final int CELL_INDEX_TARGET = 0;
125-
126-
public static PCell[] createPythonClosure(Object target, PythonObjectFactory factory, Assumption effectivelyFinal) {
127-
PCell targetCell = factory.createCell(effectivelyFinal);
128-
targetCell.setRef(target);
129-
return new PCell[]{targetCell};
130-
}
117+
public static final String KW_CALLABLE = "$callable";
118+
private static final String[] KEYWORDS_HIDDEN_CALLABLE = new String[]{KW_CALLABLE};
131119

132120
public static final class MethDirectRoot extends PRootNode {
133-
private static final Signature SIGNATURE = Signature.createVarArgsAndKwArgsOnly();
121+
122+
private static final Signature SIGNATURE = new Signature(-1, true, 0, false, null, KEYWORDS_HIDDEN_CALLABLE);
134123

135124
@Child private ExternalFunctionInvokeNode invokeNode;
136125
@Child private CalleeContext calleeContext = CalleeContext.create();
137-
@Child private CellBuiltins.GetRefNode readTargetCellNode;
126+
@Child private ReadIndexedArgumentNode readCallableNode = ReadIndexedArgumentNode.create(0);
138127

139128
private final String name;
140129

@@ -148,9 +137,7 @@ private MethDirectRoot(PythonLanguage lang, String name) {
148137
public Object execute(VirtualFrame frame) {
149138
calleeContext.enter(frame);
150139
try {
151-
PCell[] frameClosure = PArguments.getClosure(frame);
152-
assert frameClosure.length == 1 : "invalid closure for MethDirectRoot";
153-
Object callable = ensureReadTargetCellNode().execute(frameClosure[CELL_INDEX_TARGET]);
140+
Object callable = readCallableNode.execute(frame);
154141
return ensureInvokeNode().execute(frame, name, callable, PArguments.getVariableArguments(frame), 0);
155142
} finally {
156143
calleeContext.exit(frame, this);
@@ -191,14 +178,6 @@ private ExternalFunctionInvokeNode ensureInvokeNode() {
191178
return invokeNode;
192179
}
193180

194-
private GetRefNode ensureReadTargetCellNode() {
195-
if (readTargetCellNode == null) {
196-
CompilerDirectives.transferToInterpreterAndInvalidate();
197-
readTargetCellNode = insert(GetRefNode.create());
198-
}
199-
return readTargetCellNode;
200-
}
201-
202181
@TruffleBoundary
203182
public static MethDirectRoot create(PythonLanguage lang, String name) {
204183
return new MethDirectRoot(lang, name);
@@ -388,8 +367,8 @@ abstract static class MethodDescriptorRoot extends PRootNode {
388367
@Child private CalleeContext calleeContext = CalleeContext.create();
389368
@Child private CallVarargsMethodNode invokeNode;
390369
@Child private ExternalFunctionInvokeNode externalInvokeNode;
391-
@Child private CellBuiltins.GetRefNode readTargetCellNode;
392370
@Child ReadIndexedArgumentNode readSelfNode = ReadIndexedArgumentNode.create(0);
371+
@Child private ReadIndexedArgumentNode readCallableNode;
393372

394373
private final String name;
395374

@@ -412,10 +391,7 @@ abstract static class MethodDescriptorRoot extends PRootNode {
412391
public Object execute(VirtualFrame frame) {
413392
calleeContext.enter(frame);
414393
try {
415-
PCell[] frameClosure = PArguments.getClosure(frame);
416-
assert frameClosure.length == 1 : "invalid closure for MethDirectRoot";
417-
Object callable = ensureReadTargetCellNode().execute(frameClosure[CELL_INDEX_TARGET]);
418-
394+
Object callable = ensureReadCallableNode().execute(frame);
419395
if (externalInvokeNode != null) {
420396
Object[] cArguments = prepareCArguments(frame);
421397
try {
@@ -443,7 +419,8 @@ protected Object[] preparePArguments(VirtualFrame frame) {
443419
Object[] variableArguments = PArguments.getVariableArguments(frame);
444420

445421
int variableArgumentsLength = variableArguments != null ? variableArguments.length : 0;
446-
int userArgumentLength = PArguments.getUserArgumentLength(frame);
422+
// we need to subtract 1 due to the hidden default param that carries the callable
423+
int userArgumentLength = PArguments.getUserArgumentLength(frame) - 1;
447424
int argumentsLength = userArgumentLength + variableArgumentsLength;
448425
Object[] arguments = new Object[argumentsLength];
449426

@@ -469,12 +446,14 @@ static Object[] copyPArguments(VirtualFrame frame, int newUserArgumentLength) {
469446
return objects;
470447
}
471448

472-
private GetRefNode ensureReadTargetCellNode() {
473-
if (readTargetCellNode == null) {
449+
private ReadIndexedArgumentNode ensureReadCallableNode() {
450+
if (readCallableNode == null) {
474451
CompilerDirectives.transferToInterpreterAndInvalidate();
475-
readTargetCellNode = insert(GetRefNode.create());
452+
// we insert a hidden argument at the end of the positional arguments
453+
int hiddenArg = getSignature().getParameterIds().length;
454+
readCallableNode = insert(ReadIndexedArgumentNode.create(hiddenArg));
476455
}
477-
return readTargetCellNode;
456+
return readCallableNode;
478457
}
479458

480459
@Override
@@ -505,7 +484,7 @@ public boolean isPythonInternal() {
505484
}
506485

507486
public static final class MethKeywordsRoot extends MethodDescriptorRoot {
508-
private static final Signature SIGNATURE = new Signature(-1, true, 1, false, new String[]{"self"}, PythonUtils.EMPTY_STRING_ARRAY);
487+
private static final Signature SIGNATURE = new Signature(-1, true, 1, false, new String[]{"self"}, KEYWORDS_HIDDEN_CALLABLE);
509488
@Child private PythonObjectFactory factory;
510489
@Child private ReadVarArgsNode readVarargsNode;
511490
@Child private ReadVarKeywordsNode readKwargsNode;
@@ -553,7 +532,7 @@ private ReleaseNativeWrapperNode ensureReleaseNativeWrapperNode() {
553532
}
554533

555534
public static final class MethVarargsRoot extends MethodDescriptorRoot {
556-
private static final Signature SIGNATURE = new Signature(-1, false, 1, false, new String[]{"self"}, PythonUtils.EMPTY_STRING_ARRAY);
535+
private static final Signature SIGNATURE = new Signature(-1, false, 1, false, new String[]{"self"}, KEYWORDS_HIDDEN_CALLABLE);
557536
@Child private PythonObjectFactory factory;
558537
@Child private ReadVarArgsNode readVarargsNode;
559538
@Child private CreateArgsTupleNode createArgsTupleNode;
@@ -598,7 +577,7 @@ private ReleaseNativeWrapperNode ensureReleaseNativeWrapperNode() {
598577
}
599578

600579
public static final class MethNoargsRoot extends MethodDescriptorRoot {
601-
private static final Signature SIGNATURE = new Signature(-1, false, -1, false, new String[]{"self"}, PythonUtils.EMPTY_STRING_ARRAY);
580+
private static final Signature SIGNATURE = new Signature(-1, false, -1, false, new String[]{"self"}, KEYWORDS_HIDDEN_CALLABLE);
602581

603582
public MethNoargsRoot(PythonLanguage language, String name) {
604583
super(language, name);
@@ -621,7 +600,7 @@ public Signature getSignature() {
621600
}
622601

623602
public static final class MethORoot extends MethodDescriptorRoot {
624-
private static final Signature SIGNATURE = new Signature(-1, false, -1, false, new String[]{"self", "arg"}, PythonUtils.EMPTY_STRING_ARRAY);
603+
private static final Signature SIGNATURE = new Signature(-1, false, -1, false, new String[]{"self", "arg"}, KEYWORDS_HIDDEN_CALLABLE);
625604
@Child private ReadIndexedArgumentNode readArgNode;
626605

627606
public MethORoot(PythonLanguage language, String name) {
@@ -647,7 +626,7 @@ public Signature getSignature() {
647626
}
648627

649628
public static final class MethFastcallWithKeywordsRoot extends MethodDescriptorRoot {
650-
private static final Signature SIGNATURE = new Signature(-1, true, 1, false, new String[]{"self"}, PythonUtils.EMPTY_STRING_ARRAY);
629+
private static final Signature SIGNATURE = new Signature(-1, true, 1, false, new String[]{"self"}, KEYWORDS_HIDDEN_CALLABLE);
651630
@Child private PythonObjectFactory factory;
652631
@Child private ReadVarArgsNode readVarargsNode;
653632
@Child private ReadVarKeywordsNode readKwargsNode;
@@ -685,7 +664,7 @@ public Signature getSignature() {
685664
}
686665

687666
public static final class MethFastcallRoot extends MethodDescriptorRoot {
688-
private static final Signature SIGNATURE = new Signature(-1, false, 1, false, new String[]{"self"}, PythonUtils.EMPTY_STRING_ARRAY);
667+
private static final Signature SIGNATURE = new Signature(-1, false, 1, false, new String[]{"self"}, KEYWORDS_HIDDEN_CALLABLE);
689668
@Child private PythonObjectFactory factory;
690669
@Child private ReadVarArgsNode readVarargsNode;
691670

@@ -716,7 +695,7 @@ public Signature getSignature() {
716695
* Wrapper root node for C function type {@code allocfunc} and {@code ssizeargfunc}.
717696
*/
718697
static class AllocFuncRootNode extends MethodDescriptorRoot {
719-
private static final Signature SIGNATURE = new Signature(false, -1, false, new String[]{"self", "nitems"}, PythonUtils.EMPTY_STRING_ARRAY);
698+
private static final Signature SIGNATURE = new Signature(false, -1, false, new String[]{"self", "nitems"}, KEYWORDS_HIDDEN_CALLABLE);
720699
@Child private ReadIndexedArgumentNode readArgNode;
721700
@Child private ConvertPIntToPrimitiveNode asSsizeTNode;
722701

@@ -752,7 +731,7 @@ public Signature getSignature() {
752731
* Wrapper root node for a get attribute function (C type {@code getattrfunc}).
753732
*/
754733
static final class GetAttrFuncRootNode extends MethodDescriptorRoot {
755-
private static final Signature SIGNATURE = new Signature(false, -1, false, new String[]{"self", "key"}, PythonUtils.EMPTY_STRING_ARRAY);
734+
private static final Signature SIGNATURE = new Signature(false, -1, false, new String[]{"self", "key"}, KEYWORDS_HIDDEN_CALLABLE);
756735
@Child private ReadIndexedArgumentNode readArgNode;
757736
@Child private CExtNodes.AsCharPointerNode asCharPointerNode;
758737

@@ -785,7 +764,7 @@ public Signature getSignature() {
785764
* Wrapper root node for a set attribute function (C type {@code setattrfunc}).
786765
*/
787766
static final class SetAttrFuncRootNode extends MethodDescriptorRoot {
788-
private static final Signature SIGNATURE = new Signature(false, -1, false, new String[]{"self", "key", "value"}, PythonUtils.EMPTY_STRING_ARRAY);
767+
private static final Signature SIGNATURE = new Signature(false, -1, false, new String[]{"self", "key", "value"}, KEYWORDS_HIDDEN_CALLABLE);
789768
@Child private ReadIndexedArgumentNode readArg1Node;
790769
@Child private ReadIndexedArgumentNode readArg2Node;
791770
@Child private CExtNodes.AsCharPointerNode asCharPointerNode;
@@ -821,7 +800,7 @@ public Signature getSignature() {
821800
* Wrapper root node for a rich compare function (C type {@code richcmpfunc}).
822801
*/
823802
static final class RichCmpFuncRootNode extends MethodDescriptorRoot {
824-
private static final Signature SIGNATURE = new Signature(false, -1, false, new String[]{"self", "other", "op"}, PythonUtils.EMPTY_STRING_ARRAY);
803+
private static final Signature SIGNATURE = new Signature(false, -1, false, new String[]{"self", "other", "op"}, KEYWORDS_HIDDEN_CALLABLE);
825804
@Child private ReadIndexedArgumentNode readArg1Node;
826805
@Child private ReadIndexedArgumentNode readArg2Node;
827806
@Child private ConvertPIntToPrimitiveNode asSsizeTNode;
@@ -860,7 +839,7 @@ public Signature getSignature() {
860839
* Wrapper root node for C function type {@code ssizeobjargproc}.
861840
*/
862841
static final class SSizeObjArgProcRootNode extends MethodDescriptorRoot {
863-
private static final Signature SIGNATURE = new Signature(false, -1, false, new String[]{"self", "i", "value"}, PythonUtils.EMPTY_STRING_ARRAY);
842+
private static final Signature SIGNATURE = new Signature(false, -1, false, new String[]{"self", "i", "value"}, KEYWORDS_HIDDEN_CALLABLE);
864843
@Child private ReadIndexedArgumentNode readArg1Node;
865844
@Child private ReadIndexedArgumentNode readArg2Node;
866845
@Child private ConvertPIntToPrimitiveNode asSsizeTNode;
@@ -899,7 +878,7 @@ public Signature getSignature() {
899878
* Wrapper root node for reverse binary operations.
900879
*/
901880
static final class MethReverseRootNode extends MethodDescriptorRoot {
902-
private static final Signature SIGNATURE = new Signature(false, -1, false, new String[]{"self", "obj"}, PythonUtils.EMPTY_STRING_ARRAY);
881+
private static final Signature SIGNATURE = new Signature(false, -1, false, new String[]{"self", "obj"}, KEYWORDS_HIDDEN_CALLABLE);
903882
@Child private ReadIndexedArgumentNode readArg0Node;
904883
@Child private ReadIndexedArgumentNode readArg1Node;
905884

@@ -939,7 +918,7 @@ public Signature getSignature() {
939918
* Wrapper root node for native power function (with an optional third argument).
940919
*/
941920
static class MethPowRootNode extends MethodDescriptorRoot {
942-
private static final Signature SIGNATURE = new Signature(false, 0, false, new String[]{"args"}, PythonUtils.EMPTY_STRING_ARRAY);
921+
private static final Signature SIGNATURE = new Signature(false, 0, false, new String[]{"args"}, KEYWORDS_HIDDEN_CALLABLE);
943922

944923
@Child private ReadVarArgsNode readVarargsNode;
945924

@@ -998,7 +977,7 @@ Object[] getArguments(Object arg0, Object arg1, Object arg2) {
998977
* Wrapper root node for native power function (with an optional third argument).
999978
*/
1000979
static final class MethRichcmpOpRootNode extends MethodDescriptorRoot {
1001-
private static final Signature SIGNATURE = new Signature(false, -1, false, new String[]{"self", "other"}, PythonUtils.EMPTY_STRING_ARRAY);
980+
private static final Signature SIGNATURE = new Signature(false, -1, false, new String[]{"self", "other"}, KEYWORDS_HIDDEN_CALLABLE);
1002981
@Child private ReadIndexedArgumentNode readArgNode;
1003982

1004983
private final int op;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PythonCextBuiltins.java

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@
9797
import com.oracle.graal.python.builtins.objects.bytes.BytesBuiltins;
9898
import com.oracle.graal.python.builtins.objects.bytes.BytesNodes;
9999
import com.oracle.graal.python.builtins.objects.bytes.PBytes;
100-
import com.oracle.graal.python.builtins.objects.cell.PCell;
101100
import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject;
102101
import com.oracle.graal.python.builtins.objects.cext.PythonNativeClass;
103102
import com.oracle.graal.python.builtins.objects.cext.PythonNativeVoidPtr;
@@ -508,8 +507,7 @@ Object doPythonCallable(String name, PythonNativeWrapper callable, PExternalFunc
508507
Object managedCallable = nativeWrapperLibrary.getDelegate(callable);
509508
RootCallTarget wrappedCallTarget = wrapper.getOrCreateCallTarget(lang, name, false);
510509
if (wrappedCallTarget != null) {
511-
PCell[] closure = ExternalFunctionNodes.createPythonClosure(managedCallable, factory(), lang.getCallableStableAssumption());
512-
return factory().createBuiltinFunction(name, type, 0, closure, wrappedCallTarget);
510+
return factory().createBuiltinFunction(name, type, PythonUtils.EMPTY_OBJECT_ARRAY, createKwDefaults(managedCallable), wrappedCallTarget);
513511
}
514512
return managedCallable;
515513
}
@@ -539,8 +537,7 @@ Object doDecoratedManaged(String name, PyCFunctionDecorator callable, PExternalF
539537
Object managedCallable = nativeWrapperLibrary.getDelegate(callable.getNativeFunction());
540538
RootCallTarget wrappedCallTarget = wrapper.getOrCreateCallTarget(lang, name, false);
541539
if (wrappedCallTarget != null) {
542-
PCell[] closure = ExternalFunctionNodes.createPythonClosure(managedCallable, factory(), lang.getCallableStableAssumption());
543-
return factory().createBuiltinFunction(name, type, 0, closure, wrappedCallTarget);
540+
return factory().createBuiltinFunction(name, type, PythonUtils.EMPTY_OBJECT_ARRAY, createKwDefaults(managedCallable), wrappedCallTarget);
544541
}
545542

546543
// Special case: if the returned 'wrappedCallTarget' is null, this indicates we want to
@@ -554,8 +551,7 @@ PBuiltinFunction doNativeCallableWithType(String name, Object callable, PExterna
554551
@Shared("lang") @CachedLanguage PythonLanguage lang,
555552
@SuppressWarnings("unused") @CachedLibrary(limit = "2") PythonObjectLibrary lib) {
556553
RootCallTarget wrappedCallTarget = wrapper.getOrCreateCallTarget(lang, name, true);
557-
PCell[] closure = ExternalFunctionNodes.createPythonClosure(callable, factory(), lang.getCallableStableAssumption());
558-
return factory().createBuiltinFunction(name, type, 0, closure, wrappedCallTarget);
554+
return factory().createBuiltinFunction(name, type, PythonUtils.EMPTY_OBJECT_ARRAY, createKwDefaults(callable), wrappedCallTarget);
559555
}
560556

561557
@Specialization(guards = {"isNoValue(type)", "!isNativeWrapper(callable)"})
@@ -569,8 +565,7 @@ PBuiltinFunction doNativeCallableWithoutWrapper(String name, Object callable, Ob
569565
@Shared("lang") @CachedLanguage PythonLanguage lang,
570566
@SuppressWarnings("unused") @CachedLibrary(limit = "2") PythonObjectLibrary lib) {
571567
RootCallTarget callTarget = PythonUtils.getOrCreateCallTarget(MethDirectRoot.create(lang, name));
572-
PCell[] closure = ExternalFunctionNodes.createPythonClosure(callable, factory(), lang.getCallableStableAssumption());
573-
return factory().createBuiltinFunction(name, type, 0, closure, callTarget);
568+
return factory().createBuiltinFunction(name, type, PythonUtils.EMPTY_OBJECT_ARRAY, createKwDefaults(callable), callTarget);
574569
}
575570

576571
@Specialization(guards = {"isNoValue(wrapper)", "isNoValue(type)", "!isNativeWrapper(callable)"})
@@ -587,6 +582,10 @@ static boolean isDecoratedManagedFunction(Object obj) {
587582
return obj instanceof PyCFunctionDecorator && CApiGuards.isNativeWrapper(((PyCFunctionDecorator) obj).getNativeFunction());
588583
}
589584

585+
private static PKeyword[] createKwDefaults(Object callable) {
586+
return new PKeyword[]{new PKeyword(ExternalFunctionNodes.KW_CALLABLE, callable)};
587+
}
588+
590589
public static CreateFunctionNode create() {
591590
return CreateFunctionNodeFactory.create(null);
592591
}

0 commit comments

Comments
 (0)