Skip to content

Commit 4b48221

Browse files
committed
[GR-31702] add couple of native missing functions
PullRequest: graalpython/1821
2 parents 4f236f7 + 7914804 commit 4b48221

File tree

4 files changed

+93
-1
lines changed

4 files changed

+93
-1
lines changed

graalpython/com.oracle.graal.python.cext/include/cpython/abstract.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ _PyObject_FastCall(PyObject *func, PyObject *const *args, Py_ssize_t nargs)
155155
/* Call a callable without any arguments */
156156
static inline PyObject *
157157
_PyObject_CallNoArg(PyObject *func) {
158-
return _PyObject_Vectorcall(func, NULL, 0, NULL);
158+
return PyObject_CallObject(func, NULL); /* Truffle change: redirect to PyObject_CallObject until _PyObject_Vectorcall is implemented */
159159
}
160160

161161
PyAPI_FUNC(PyObject *) _PyObject_Call_Prepend(

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@ PyObject* PyDict_GetItemWithError(PyObject* d, PyObject* k) {
6767
return UPCALL_CEXT_BORROWED(_jls_PyDict_GetItemWithError, native_to_java(d), native_to_java(k));
6868
}
6969

70+
PyObject *
71+
_PyDict_GetItemIdWithError(PyObject *dp, struct _Py_Identifier *key)
72+
{
73+
PyObject *kv;
74+
kv = _PyUnicode_FromId(key); /* borrowed */
75+
if (kv == NULL)
76+
return NULL;
77+
return PyDict_GetItemWithError(dp, kv);
78+
}
79+
7080
PyObject* _PyDict_GetItemId(PyObject* d, _Py_Identifier* id) {
7181
return PyDict_GetItemString(d, id->string);
7282
}

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

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,68 @@ PyObject * PyObject_GetAttr(PyObject *v, PyObject *name) {
433433
return NULL;
434434
}
435435

436+
// taken from CPython "Objects/object.c"
437+
int _PyObject_LookupAttr(PyObject *v, PyObject *name, PyObject **result)
438+
{
439+
PyTypeObject *tp = Py_TYPE(v);
440+
441+
if (!PyUnicode_Check(name)) {
442+
PyErr_Format(PyExc_TypeError,
443+
"attribute name must be string, not '%.200s'",
444+
name->ob_type->tp_name);
445+
*result = NULL;
446+
return -1;
447+
}
448+
449+
/* Truffle change: this fast path is only applicable to cpython
450+
if (tp->tp_getattro == PyObject_GenericGetAttr) {
451+
*result = _PyObject_GenericGetAttrWithDict(v, name, NULL, 1);
452+
if (*result != NULL) {
453+
return 1;
454+
}
455+
if (PyErr_Occurred()) {
456+
return -1;
457+
}
458+
return 0;
459+
}
460+
*/
461+
if (tp->tp_getattro != NULL) {
462+
*result = (*tp->tp_getattro)(v, name);
463+
}
464+
else if (tp->tp_getattr != NULL) {
465+
const char *name_str = PyUnicode_AsUTF8(name);
466+
if (name_str == NULL) {
467+
*result = NULL;
468+
return -1;
469+
}
470+
*result = (*tp->tp_getattr)(v, (char *)name_str);
471+
}
472+
else {
473+
*result = NULL;
474+
return 0;
475+
}
476+
477+
if (*result != NULL) {
478+
return 1;
479+
}
480+
if (!PyErr_ExceptionMatches(PyExc_AttributeError)) {
481+
return -1;
482+
}
483+
PyErr_Clear();
484+
return 0;
485+
}
486+
487+
// taken from CPython "Objects/object.c"
488+
int _PyObject_LookupAttrId(PyObject *v, _Py_Identifier *name, PyObject **result)
489+
{
490+
PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
491+
if (!oname) {
492+
*result = NULL;
493+
return -1;
494+
}
495+
return _PyObject_LookupAttr(v, oname, result);
496+
}
497+
436498
UPCALL_ID(PyObject_GenericGetAttr);
437499
PyObject* PyObject_GenericGetAttr(PyObject* obj, PyObject* attr) {
438500
PyTypeObject *tp = Py_TYPE(obj);
@@ -486,6 +548,17 @@ int PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value) {
486548
return -1;
487549
}
488550

551+
// taken from CPython "Objects/object.c"
552+
int _PyObject_SetAttrId(PyObject *v, _Py_Identifier *name, PyObject *w)
553+
{
554+
int result;
555+
PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
556+
if (!oname)
557+
return -1;
558+
result = PyObject_SetAttr(v, oname, w);
559+
return result;
560+
}
561+
489562
UPCALL_ID(PyObject_GenericSetAttr);
490563
int PyObject_GenericSetAttr(PyObject* obj, PyObject* attr, PyObject* value) {
491564
PyTypeObject *tp = Py_TYPE(obj);

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,15 @@ def forgiving_len(o):
147147
argspec="OOO",
148148
callfunction="wrap_PyObject_Call",
149149
)
150+
test__PyObject_CallNoArg = CPyExtFunction(
151+
lambda args: args[0](),
152+
lambda: (
153+
(dict, ),
154+
(list, ),
155+
),
156+
arguments=["PyObject* callable"],
157+
argspec="O",
158+
)
150159
test_PyObject_CallObject = CPyExtFunction(
151160
lambda args: args[0](*args[1]),
152161
lambda: (

0 commit comments

Comments
 (0)