Skip to content

Commit ed4a42c

Browse files
committed
Add support for calling managed class tp_init from native
1 parent a75eaf4 commit ed4a42c

File tree

9 files changed

+72
-7
lines changed

9 files changed

+72
-7
lines changed

graalpython/com.oracle.graal.python.cext/src/typeobject.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -486,8 +486,8 @@ int PyType_Ready(PyTypeObject* cls) {
486486
} else {
487487
bases = PyTuple_Pack(1, base);
488488
}
489+
cls->tp_bases = bases;
489490
}
490-
cls->tp_bases = bases;
491491

492492
/* Initialize tp_dict */
493493
PyObject* dict = cls->tp_dict;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ private static void handleException(PythonContext context, PException e) {
136136
@Specialization
137137
Object register(Object callable, Object[] arguments, PKeyword[] keywords) {
138138
CompilerDirectives.transferToInterpreter();
139-
RootCallTarget callTarget = PythonLanguage.getCurrent().createCachedCallTarget(l -> new AtExitRootNode(l), AtExitRootNode.class);
139+
RootCallTarget callTarget = PythonLanguage.getCurrent().createCachedCallTarget(AtExitRootNode::new, AtExitRootNode.class);
140140
getContext().registerAtexitHook(callable, arguments, keywords, callTarget);
141141
return callable;
142142
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/PythonAbstractObject.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,7 +730,7 @@ public long hashWithState(ThreadState state,
730730
@Exclusive @Cached CastUnsignedToJavaLongHashNode castUnsignedToJavaLongHashNode) {
731731
Object hashMethod = lib.lookupAttributeOnType(this, __HASH__);
732732
if (!methodLib.isCallable(hashMethod) && lookupGet.execute(hashMethod, __GET__) == PNone.NO_VALUE) {
733-
throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNHASHABLE_TYPE, this);
733+
throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNHASHABLE_TYPE_P, this);
734734
}
735735
Object result = methodLib.callUnboundMethodIgnoreGetExceptionWithState(hashMethod, state, this);
736736
// see PyObject_GetHash and slot_tp_hash in CPython. The result of the

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiContext.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -495,10 +495,9 @@ public PythonAbstractNativeObject getPythonNativeObject(TruffleObject nativePtr,
495495
if (newRefProfile.profile(id == 0)) {
496496
return createPythonAbstractNativeObject(nativePtr, addRefCntNode, steal, attachLLVMTypeNode);
497497
} else if (validRefProfile.profile(id > 0)) {
498-
PythonAbstractNativeObject nativeObject;
499498
ref = lookupNativeObjectReference(id);
500499
if (ref != null) {
501-
nativeObject = ref.get();
500+
PythonAbstractNativeObject nativeObject = ref.get();
502501
if (resurrectProfile.profile(nativeObject == null)) {
503502
// Bad luck: the mapping is still there and wasn't cleaned up but we need a new
504503
// mapping. Therefore, we need to cancel the cleaner action and set a new native

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/DynamicObjectNativeWrapper.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
import static com.oracle.graal.python.nodes.SpecialMethodNames.RICHCMP;
6868
import static com.oracle.graal.python.nodes.SpecialMethodNames.__GETATTRIBUTE__;
6969
import static com.oracle.graal.python.nodes.SpecialMethodNames.__HASH__;
70+
import static com.oracle.graal.python.nodes.SpecialMethodNames.__INIT__;
7071
import static com.oracle.graal.python.nodes.SpecialMethodNames.__LEN__;
7172
import static com.oracle.graal.python.nodes.SpecialMethodNames.__NEW__;
7273
import static com.oracle.graal.python.nodes.SpecialMethodNames.__NEXT__;
@@ -533,6 +534,13 @@ static Object doTpNew(PythonManagedClass object, @SuppressWarnings("unused") Pyt
533534
return ManagedMethodWrappers.createKeywords(newFunction, callGetNewfuncTypeidNode.call(NativeCAPISymbol.FUN_GET_NEWFUNC_TYPE_ID));
534535
}
535536

537+
@Specialization(guards = "eq(TP_INIT, key)")
538+
static Object doTpInit(PythonManagedClass object, @SuppressWarnings("unused") PythonNativeWrapper nativeWrapper, @SuppressWarnings("unused") String key,
539+
@Cached LookupAttributeInMRONode.Dynamic getAttrNode) {
540+
Object initFun = getAttrNode.execute(object, __INIT__);
541+
return PyProcsWrapper.createInitWrapper(initFun);
542+
}
543+
536544
@Specialization(guards = "eq(TP_HASH, key)")
537545
static Object doTpHash(PythonManagedClass object, @SuppressWarnings("unused") PythonNativeWrapper nativeWrapper, @SuppressWarnings("unused") String key,
538546
@Cached LookupAttributeInMRONode.Dynamic getHashNode,

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/NativeMember.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ public enum NativeMember {
9797
TP_SETATTRO("tp_setattro"),
9898
TP_ITERNEXT("tp_iternext"),
9999
TP_NEW("tp_new"),
100+
TP_INIT("tp_init"),
100101
TP_DICT("tp_dict", OBJECT),
101102
TP_STR("tp_str"),
102103
TP_REPR("tp_repr"),

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyProcsWrapper.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@
4949
import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.TransformExceptionToNativeNode;
5050
import com.oracle.graal.python.builtins.objects.cext.capi.DynamicObjectNativeWrapper.PAsPointerNode;
5151
import com.oracle.graal.python.builtins.objects.cext.capi.DynamicObjectNativeWrapper.ToPyObjectNode;
52+
import com.oracle.graal.python.builtins.objects.function.PKeyword;
53+
import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode;
54+
import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode;
55+
import com.oracle.graal.python.nodes.argument.positional.PositionalArgumentsNode;
56+
import com.oracle.graal.python.nodes.call.CallNode;
5257
import com.oracle.graal.python.nodes.call.special.CallBinaryMethodNode;
5358
import com.oracle.graal.python.nodes.call.special.CallTernaryMethodNode;
5459
import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile;
@@ -196,6 +201,53 @@ protected int execute(Object[] arguments,
196201

197202
}
198203

204+
@ExportLibrary(InteropLibrary.class)
205+
static class InitWrapper extends PyProcsWrapper {
206+
207+
public InitWrapper(Object delegate) {
208+
super(delegate);
209+
}
210+
211+
@ExportMessage
212+
protected int execute(Object[] arguments,
213+
@CachedLibrary("this") PythonNativeWrapperLibrary lib,
214+
@Cached ExecutePositionalStarargsNode.ExecutePositionalStarargsInteropNode posStarargsNode,
215+
@Cached ExpandKeywordStarargsNode expandKwargsNode,
216+
@Exclusive @Cached CallNode callNode,
217+
@Cached ToJavaNode toJavaNode,
218+
@Cached ConditionProfile arityProfile,
219+
@Cached BranchProfile errorProfile,
220+
@Cached TransformExceptionToNativeNode transformExceptionToNativeNode,
221+
@Exclusive @Cached GilNode gil) throws ArityException {
222+
boolean mustRelease = gil.acquire();
223+
try {
224+
if (arityProfile.profile(arguments.length != 3)) {
225+
CompilerDirectives.transferToInterpreterAndInvalidate();
226+
throw ArityException.create(3, 3, arguments.length);
227+
}
228+
try {
229+
// convert args
230+
Object receiver = toJavaNode.execute(arguments[0]);
231+
Object starArgs = toJavaNode.execute(arguments[1]);
232+
Object kwArgs = toJavaNode.execute(arguments[2]);
233+
234+
Object[] starArgsArray = posStarargsNode.executeWithGlobalState(starArgs);
235+
Object[] pArgs = PositionalArgumentsNode.prependArgument(receiver, starArgsArray);
236+
PKeyword[] kwArgsArray = expandKwargsNode.execute(kwArgs);
237+
callNode.execute(null, lib.getDelegate(this), pArgs, kwArgsArray);
238+
return 0;
239+
} catch (PException e) {
240+
errorProfile.enter();
241+
transformExceptionToNativeNode.execute(null, e);
242+
return -1;
243+
}
244+
} finally {
245+
gil.release(mustRelease);
246+
}
247+
}
248+
249+
}
250+
199251
@ExportLibrary(InteropLibrary.class)
200252
static class SsizeargfuncWrapper extends PyProcsWrapper {
201253

@@ -245,6 +297,10 @@ public static SetAttrWrapper createSetAttrWrapper(Object setAttrMethod) {
245297
return new SetAttrWrapper(setAttrMethod);
246298
}
247299

300+
public static InitWrapper createInitWrapper(Object setInitMethod) {
301+
return new InitWrapper(setInitMethod);
302+
}
303+
248304
public static SsizeargfuncWrapper createSsizeargfuncWrapper(Object ssizeArgMethod, boolean newRef) {
249305
return new SsizeargfuncWrapper(ssizeArgMethod, newRef);
250306
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/slice/SliceBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,7 @@ public abstract static class HashNode extends PythonBuiltinNode {
221221
public static long hash(PSlice self,
222222
@Cached PRaiseNode raise) {
223223
CompilerDirectives.transferToInterpreter();
224-
throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNHASHABLE_TYPE, PythonBuiltinClassType.PSlice);
224+
throw raise.raise(PythonBuiltinClassType.TypeError, ErrorMessages.UNHASHABLE_TYPE_P, PythonBuiltinClassType.PSlice);
225225
}
226226
}
227227

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,8 @@ public abstract class ErrorMessages {
592592
public static final String UNAVAILABLE_ON_THIS_PLATFORM = "%s: %s unavailable on this platform";
593593
public static final String UNAVAILABLE_ON_THIS_PLATFORM_NO_FUNC = "%s unavailable on this platform";
594594
public static final String UNEXPECTED_KEYWORD_ARGS = "%s: unexpected keyword arguments";
595-
public static final String UNHASHABLE_TYPE = "unhashable type: '%p'";
595+
public static final String UNHASHABLE_TYPE_P = "unhashable type: '%p'";
596+
public static final String UNHASHABLE_TYPE = "unhashable type";
596597
public static final String UNINITIALIZED_S_OBJECT = "uninitialized classmethod object";
597598
public static final String UNKNOWN_ADDR_FAMILY = "unknown address family %d";
598599
public static final String UNKNOWN_ATTR = "Unknown attribute: '%s'";

0 commit comments

Comments
 (0)