Skip to content

Commit 31c19ec

Browse files
committed
[GR-34916] Intrinsify python_cext - instancemethod.
PullRequest: graalpython/2126
2 parents ec1ba94 + 6c83bd2 commit 31c19ec

File tree

21 files changed

+542
-155
lines changed

21 files changed

+542
-155
lines changed

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -308,10 +308,6 @@ static void initialize_globals() {
308308
void *jfalse = UPCALL_CEXT_O(polyglot_from_string("Py_False", SRC_CS));
309309
truffle_assign_managed(&_Py_FalseStruct, jfalse);
310310

311-
// error marker
312-
void *jerrormarker = UPCALL_CEXT_PTR(polyglot_from_string("Py_ErrorHandler", SRC_CS));
313-
truffle_assign_managed(&marker_struct, jerrormarker);
314-
315311
// long zero, long one
316312
_PyLong_Zero = (PyObject *)&_Py_FalseStruct;
317313
_PyLong_One = (PyObject *)&_Py_TrueStruct;

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -62,11 +62,6 @@ PyObject* PyDictProxy_New(PyObject *mapping) {
6262
return (PyObject*) UPCALL_CEXT_O(_jls_PyDictProxy_New, native_to_java(mapping));
6363
}
6464

65-
UPCALL_ID(PyMethodDescr_Check);
66-
int PyMethodDescr_Check(PyObject* method) {
67-
return UPCALL_CEXT_I(_jls_PyMethodDescr_Check, native_to_java(method));
68-
}
69-
7065
typedef PyObject* (*PyDescr_NewClassMethod_fun_t)(void* name,
7166
const char* doc,
7267
int flags,

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -41,9 +41,14 @@
4141

4242
#include "capi.h"
4343

44+
PyTypeObject PyFunction_Type = PY_TRUFFLE_TYPE_WITH_VECTORCALL("function", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_METHOD_DESCRIPTOR | _Py_TPFLAGS_HAVE_VECTORCALL, sizeof(PyFunctionObject), offsetof(PyFunctionObject, vectorcall));
4445
PyTypeObject PyStaticMethod_Type = PY_TRUFFLE_TYPE("staticmethod", &PyType_Type, Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC, sizeof(PyType_Type));
4546

4647
UPCALL_ID(PyStaticMethod_New)
4748
PyObject* PyStaticMethod_New(PyObject *callable) {
48-
return UPCALL_CEXT_O(_jls_PyStaticMethod_New, callable);
49+
return UPCALL_CEXT_O(_jls_PyStaticMethod_New, native_to_java(callable));
50+
}
51+
52+
PyObject* PyClassMethod_New(PyObject* method) {
53+
return UPCALL_O(PY_BUILTIN, polyglot_from_string("classmethod", SRC_CS), native_to_java(method));
4954
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0
@@ -443,7 +443,7 @@ MUST_INLINE static PyObject* _PyTruffle_BuildValue(const char* format, va_list v
443443
if (v->prev == NULL) {
444444
PyErr_SetString(PyExc_SystemError, "'}' without '{' in Py_BuildValue");
445445
} else {
446-
PyList_Append(v->prev->list, to_sulong(polyglot_invoke(PY_TRUFFLE_CEXT, "dict_from_list", to_java(v->list))));
446+
PyList_Append(v->prev->list, to_sulong(polyglot_invoke(PY_TRUFFLE_CEXT, "PyTruffle_Dict_From_List", to_java(v->list))));
447447
next = v;
448448
v = v->prev;
449449
free(next);

graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_functions.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ def compile_module(self, name):
7272
type,
7373
lambda: ([], 12, sys.modules)
7474
)
75-
75+
7676
# Below are the PyObject_* identifiers that we know are used in numpy
77-
77+
7878
def is_buffer(x):
7979
__breakpoint__()
8080
if (isinstance(x, bytes) or isinstance(x, bytearray) or isinstance(x, array.array)):
@@ -459,3 +459,14 @@ def _ref_hash_not_implemented(args):
459459
# )
460460
# test_PyObject_Init = CPyExtFunction(
461461
# )
462+
463+
test_PyStaticMethod_New = CPyExtFunction(
464+
lambda args: None,
465+
lambda: (
466+
(kw_fun,),
467+
),
468+
resultspec="O",
469+
arguments=["PyObject* func"],
470+
argspec="O",
471+
cmpfunc=lambda x, y: type(x) == staticmethod
472+
)

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@
110110
import com.oracle.graal.python.builtins.modules.bz2.BZ2DecompressorBuiltins;
111111
import com.oracle.graal.python.builtins.modules.bz2.BZ2ModuleBuiltins;
112112
import com.oracle.graal.python.builtins.modules.cext.PythonCextBytesBuiltins;
113+
import com.oracle.graal.python.builtins.modules.cext.PythonCextClassBuiltins;
113114
import com.oracle.graal.python.builtins.modules.cext.PythonCextComplexBuiltins;
114115
import com.oracle.graal.python.builtins.modules.cext.PythonCextCEvalBuiltins;
115116
import com.oracle.graal.python.builtins.modules.cext.PythonCextCodeBuiltins;
@@ -122,6 +123,8 @@
122123
import com.oracle.graal.python.builtins.modules.cext.PythonCextMemoryViewBuiltins;
123124
import com.oracle.graal.python.builtins.modules.cext.PythonCextAbstractBuiltins;
124125
import com.oracle.graal.python.builtins.modules.cext.PythonCextErrBuiltins;
126+
import com.oracle.graal.python.builtins.modules.cext.PythonCextDescrBuiltins;
127+
import com.oracle.graal.python.builtins.modules.cext.PythonCextFuncBuiltins;
125128
import com.oracle.graal.python.builtins.modules.cext.PythonCextIterBuiltins;
126129
import com.oracle.graal.python.builtins.modules.cext.PythonCextModuleBuiltins;
127130
import com.oracle.graal.python.builtins.modules.cext.PythonCextNamespaceBuiltins;
@@ -263,6 +266,7 @@
263266
import com.oracle.graal.python.builtins.objects.method.BuiltinMethodBuiltins;
264267
import com.oracle.graal.python.builtins.objects.method.ClassmethodBuiltins;
265268
import com.oracle.graal.python.builtins.objects.method.DecoratedMethodBuiltins;
269+
import com.oracle.graal.python.builtins.objects.method.InstancemethodBuiltins;
266270
import com.oracle.graal.python.builtins.objects.method.MethodBuiltins;
267271
import com.oracle.graal.python.builtins.objects.method.PMethod;
268272
import com.oracle.graal.python.builtins.objects.method.StaticmethodBuiltins;
@@ -421,6 +425,7 @@ private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed)
421425
new DecoratedMethodBuiltins(),
422426
new ClassmethodBuiltins(),
423427
new StaticmethodBuiltins(),
428+
new InstancemethodBuiltins(),
424429
new SimpleNamespaceBuiltins(),
425430
new PolyglotModuleBuiltins(),
426431
new ObjectBuiltins(),
@@ -492,10 +497,13 @@ private static PythonBuiltins[] initializeBuiltins(boolean nativeAccessAllowed)
492497
new PythonCextCEvalBuiltins(),
493498
new PythonCextCodeBuiltins(),
494499
new PythonCextComplexBuiltins(),
500+
new PythonCextClassBuiltins(),
501+
new PythonCextDescrBuiltins(),
495502
new PythonCextDictBuiltins(),
496503
new PythonCextErrBuiltins(),
497504
new PythonCextFileBuiltins(),
498505
new PythonCextFloatBuiltins(),
506+
new PythonCextFuncBuiltins(),
499507
new PythonCextImportBuiltins(),
500508
new PythonCextIterBuiltins(),
501509
new PythonCextListBuiltins(),

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2021, Oracle and/or its affiliates.
2+
* Copyright (c) 2017, 2022, Oracle and/or its affiliates.
33
* Copyright (c) 2013, Regents of the University of California
44
*
55
* All rights reserved.
@@ -150,6 +150,7 @@ public enum PythonBuiltinClassType implements TruffleObject {
150150
PSocket("socket", "_socket"),
151151
PStaticmethod("staticmethod", BUILTINS, Flags.PUBLIC_BASE_WDICT),
152152
PClassmethod("classmethod", BUILTINS, Flags.PUBLIC_BASE_WDICT),
153+
PInstancemethod("instancemethod", BUILTINS, Flags.PUBLIC_BASE_WDICT),
153154
PScandirIterator("ScandirIterator", "posix", Flags.PRIVATE_DERIVED_WODICT),
154155
PDirEntry("DirEntry", "posix", Flags.PUBLIC_DERIVED_WODICT),
155156
LsprofProfiler("Profiler", "_lsprof"),

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import static com.oracle.graal.python.nodes.BuiltinNames.BYTEARRAY;
3535
import static com.oracle.graal.python.nodes.BuiltinNames.BYTES;
3636
import static com.oracle.graal.python.nodes.BuiltinNames.CLASSMETHOD;
37+
import static com.oracle.graal.python.nodes.BuiltinNames.INSTANCEMETHOD;
3738
import static com.oracle.graal.python.nodes.BuiltinNames.COMPLEX;
3839
import static com.oracle.graal.python.nodes.BuiltinNames.DICT;
3940
import static com.oracle.graal.python.nodes.BuiltinNames.DICT_ITEMITERATOR;
@@ -3362,6 +3363,15 @@ Object doObjectIndirect(Object self, @SuppressWarnings("unused") Object callable
33623363
}
33633364
}
33643365

3366+
@Builtin(name = INSTANCEMETHOD, minNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PInstancemethod, isPublic = false, doc = "instancemethod(function)\n\nBind a function to a class.")
3367+
@GenerateNodeFactory
3368+
public abstract static class InstancemethodNode extends PythonBinaryBuiltinNode {
3369+
@Specialization
3370+
Object doObjectIndirect(Object self, @SuppressWarnings("unused") Object callable) {
3371+
return factory().createInstancemethod(self);
3372+
}
3373+
}
3374+
33653375
@Builtin(name = STATICMETHOD, minNumOfPositionalArgs = 2, constructsClass = PythonBuiltinClassType.PStaticmethod)
33663376
@GenerateNodeFactory
33673377
public abstract static class StaticmethodNode extends PythonBinaryBuiltinNode {

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

Lines changed: 32 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError;
4545
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
4646
import static com.oracle.graal.python.builtins.objects.cext.common.CExtContext.METH_CLASS;
47-
import static com.oracle.graal.python.builtins.objects.cext.common.CExtContext.isClassOrStaticMethod;
47+
import static com.oracle.graal.python.nodes.ErrorMessages.LIST_CANNOT_BE_CONVERTED_TO_DICT;
4848
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__DOC__;
4949
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__MODULE__;
5050
import static com.oracle.graal.python.nodes.SpecialAttributeNames.__NAME__;
@@ -76,7 +76,6 @@
7676
import com.oracle.graal.python.builtins.Python3Core;
7777
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
7878
import com.oracle.graal.python.builtins.PythonBuiltins;
79-
import com.oracle.graal.python.builtins.modules.BuiltinConstructors.MappingproxyNode;
8079
import com.oracle.graal.python.builtins.modules.SysModuleBuiltins;
8180
import com.oracle.graal.python.builtins.modules.cext.PythonCextBuiltinsFactory.CreateFunctionNodeGen;
8281
import com.oracle.graal.python.builtins.objects.PNone;
@@ -179,6 +178,7 @@
179178
import com.oracle.graal.python.builtins.objects.function.Signature;
180179
import com.oracle.graal.python.builtins.objects.getsetdescriptor.GetSetDescriptor;
181180
import com.oracle.graal.python.builtins.objects.ints.PInt;
181+
import com.oracle.graal.python.builtins.objects.list.ListBuiltins;
182182
import com.oracle.graal.python.builtins.objects.memoryview.BufferLifecycleManager;
183183
import com.oracle.graal.python.builtins.objects.memoryview.MemoryViewNodes;
184184
import com.oracle.graal.python.builtins.objects.memoryview.NativeBufferLifecycleManager;
@@ -195,7 +195,6 @@
195195
import com.oracle.graal.python.builtins.objects.tuple.StructSequence.Descriptor;
196196
import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass;
197197
import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass;
198-
import com.oracle.graal.python.builtins.objects.type.PythonClass;
199198
import com.oracle.graal.python.builtins.objects.type.PythonManagedClass;
200199
import com.oracle.graal.python.builtins.objects.type.SpecialMethodSlot;
201200
import com.oracle.graal.python.builtins.objects.type.TypeNodes;
@@ -287,7 +286,9 @@
287286
import com.oracle.truffle.api.nodes.RootNode;
288287
import com.oracle.truffle.api.object.DynamicObjectLibrary;
289288
import com.oracle.truffle.api.object.HiddenKey;
289+
import com.oracle.truffle.api.profiles.BranchProfile;
290290
import com.oracle.truffle.api.profiles.ConditionProfile;
291+
import com.oracle.truffle.api.profiles.LoopConditionProfile;
291292
import com.oracle.truffle.api.profiles.ValueProfile;
292293
import com.oracle.truffle.api.utilities.CyclicAssumption;
293294

@@ -297,7 +298,6 @@ public final class PythonCextBuiltins extends PythonBuiltins {
297298

298299
public static final String PYTHON_CEXT = "python_cext";
299300

300-
private static final String ERROR_HANDLER = "error_handler";
301301
public static final String NATIVE_NULL = "native_null";
302302

303303
private PythonObject errorHandler;
@@ -310,11 +310,6 @@ protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFa
310310
@Override
311311
public void initialize(Python3Core core) {
312312
super.initialize(core);
313-
PythonClass errorHandlerClass = core.factory().createPythonClassAndFixupSlots(core.getLanguage(), PythonBuiltinClassType.PythonClass,
314-
"CErrorHandler", new PythonAbstractClass[]{core.lookupType(PythonBuiltinClassType.PythonObject)});
315-
builtinConstants.put("CErrorHandler", errorHandlerClass);
316-
errorHandler = core.factory().createPythonObject(errorHandlerClass);
317-
builtinConstants.put(ERROR_HANDLER, errorHandler);
318313
// TODO can be removed when python_cext.py is gone
319314
builtinConstants.put(NATIVE_NULL, core.getContext().getNativeNull());
320315
builtinConstants.put("PyEval_SaveThread", new PyEvalSaveThread());
@@ -380,15 +375,6 @@ Object run(VirtualFrame frame, Object o) {
380375
}
381376
}
382377

383-
@Builtin(name = "Py_ErrorHandler", minNumOfPositionalArgs = 1, declaresExplicitSelf = true)
384-
@GenerateNodeFactory
385-
public abstract static class PyErrorHandlerNode extends PythonUnaryBuiltinNode {
386-
@Specialization
387-
static Object run(PythonModule cextPython) {
388-
return ((PythonCextBuiltins) cextPython.getBuiltins()).errorHandler;
389-
}
390-
}
391-
392378
@Builtin(name = "Py_NotImplemented")
393379
@GenerateNodeFactory
394380
public abstract static class PyNotImplementedNode extends PythonBuiltinNode {
@@ -425,15 +411,36 @@ static Object run() {
425411
}
426412
}
427413

428-
///////////// mappingproxy /////////////
429-
430-
@Builtin(name = "PyDictProxy_New", minNumOfPositionalArgs = 1)
414+
@Builtin(name = "PyTruffle_Dict_From_List", minNumOfPositionalArgs = 1)
431415
@GenerateNodeFactory
432-
public abstract static class PyDictProxyNewNode extends PythonUnaryBuiltinNode {
416+
public abstract static class DictFromListNode extends PythonUnaryBuiltinNode {
433417
@Specialization
434-
public static Object values(VirtualFrame frame, Object obj,
435-
@Cached MappingproxyNode mappingNode) {
436-
return mappingNode.execute(frame, PythonBuiltinClassType.PMappingproxy, obj);
418+
public Object values(VirtualFrame frame, Object list,
419+
@Cached com.oracle.graal.python.lib.PyObjectSizeNode sizeNode,
420+
@Cached ListBuiltins.GetItemNode getItemNode,
421+
@Cached BranchProfile wrongLenProfile,
422+
@Cached LoopConditionProfile loopProfile,
423+
@CachedLibrary(limit = "3") HashingStorageLibrary lib,
424+
@Cached PRaiseNativeNode raiseNativeNode,
425+
@Cached TransformExceptionToNativeNode transformExceptionToNativeNode) {
426+
try {
427+
int size = sizeNode.execute(frame, list);
428+
if (size % 2 != 0) {
429+
wrongLenProfile.enter();
430+
return raiseNativeNode.raise(frame, getContext().getNativeNull(), PythonBuiltinClassType.SystemError, LIST_CANNOT_BE_CONVERTED_TO_DICT);
431+
}
432+
HashingStorage store = PDict.createNewStorage(false, size);
433+
loopProfile.profileCounted(size);
434+
for (int i = 0; loopProfile.profile(i < size); i = i + 2) {
435+
Object k = getItemNode.execute(frame, list, i);
436+
Object v = getItemNode.execute(frame, list, i + 1);
437+
store = lib.setItem(store, k, v);
438+
}
439+
return factory().createDict(store);
440+
} catch (PException e) {
441+
transformExceptionToNativeNode.execute(e);
442+
return getContext().getNativeNull();
443+
}
437444
}
438445
}
439446

@@ -2407,34 +2414,6 @@ private static void addSlot(Object clsPtr, Object tpDictPtr, Object namePtr, Obj
24072414
}
24082415
}
24092416

2410-
// directly called without landing function
2411-
@Builtin(name = "PyDescr_NewClassMethod", minNumOfPositionalArgs = 6, parameterNames = {"name", "doc", "flags", "wrapper", "cfunc", "primary"})
2412-
@ArgumentClinic(name = "name", conversion = ArgumentClinic.ClinicConversion.String)
2413-
@GenerateNodeFactory
2414-
abstract static class PyDescrNewClassMethod extends PythonClinicBuiltinNode {
2415-
@Override
2416-
protected ArgumentClinicProvider getArgumentClinic() {
2417-
return PythonCextBuiltinsClinicProviders.PyDescrNewClassMethodClinicProviderGen.INSTANCE;
2418-
}
2419-
2420-
@Specialization
2421-
Object doNativeCallable(String name, Object doc, int flags, Object wrapper, Object methObj, Object primary,
2422-
@Cached AsPythonObjectNode asPythonObjectNode,
2423-
@Cached NewClassMethodNode newClassMethodNode,
2424-
@Cached ToNewRefNode newRefNode) {
2425-
Object type = asPythonObjectNode.execute(primary);
2426-
Object func = newClassMethodNode.execute(name, methObj, flags, wrapper, type, doc, factory());
2427-
if (!isClassOrStaticMethod(flags)) {
2428-
/*
2429-
* NewClassMethodNode only wraps method with METH_CLASS and METH_STATIC set but we
2430-
* need to do so here.
2431-
*/
2432-
func = factory().createClassmethodFromCallableObj(func);
2433-
}
2434-
return newRefNode.execute(func);
2435-
}
2436-
}
2437-
24382417
abstract static class CFunctionNewExMethodNode extends Node {
24392418

24402419
abstract Object execute(String name, Object methObj, Object flags, Object wrapper, Object self, Object module, Object doc,
@@ -2658,26 +2637,6 @@ private static RootCallTarget setterCallTarget(String name, PythonLanguage lang)
26582637
}
26592638
}
26602639

2661-
// directly called without landing function
2662-
@Builtin(name = "PyDescr_NewGetSet", minNumOfPositionalArgs = 6, parameterNames = {"name", "cls", "getter", "setter", "doc", "closure"})
2663-
@ArgumentClinic(name = "name", conversion = ClinicConversion.String)
2664-
@GenerateNodeFactory
2665-
abstract static class PyDescrNewGetSetNode extends PythonClinicBuiltinNode {
2666-
@Override
2667-
protected ArgumentClinicProvider getArgumentClinic() {
2668-
return PythonCextBuiltinsClinicProviders.PyDescrNewGetSetNodeClinicProviderGen.INSTANCE;
2669-
}
2670-
2671-
@Specialization
2672-
Object doNativeCallable(String name, Object cls, Object getter, Object setter, Object doc, Object closure,
2673-
@Cached CreateGetSetNode createGetSetNode,
2674-
@Cached CExtNodes.ToSulongNode toSulongNode) {
2675-
GetSetDescriptor descr = createGetSetNode.execute(name, cls, getter, setter, doc, closure,
2676-
getLanguage(), factory());
2677-
return toSulongNode.execute(descr);
2678-
}
2679-
}
2680-
26812640
// directly called without landing function
26822641
@Builtin(name = "AddGetSet", minNumOfPositionalArgs = 7, parameterNames = {"cls", "tpDict", "name", "getter", "setter", "doc", "closure"})
26832642
@ArgumentClinic(name = "name", conversion = ClinicConversion.String)

0 commit comments

Comments
 (0)