Skip to content

Commit 4b55a5c

Browse files
committed
[GR-34916] Intrinsify python_cext - PySequence/Mapping/Object_check/size.
PullRequest: graalpython/2110
2 parents ad761fd + d61ce4c commit 4b55a5c

27 files changed

+848
-336
lines changed

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

Lines changed: 72 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,42 @@ int PySequence_Check(PyObject *s) {
285285
return UPCALL_CEXT_I(_jls_PySequence_Check, native_to_java(s));
286286
}
287287

288-
UPCALL_ID(PyObject_Size);
288+
// downcall for native python objects
289+
// taken from CPython "Objects/abstract.c PySequence_Check()"
290+
int PyTruffle_PySequence_Check(PyObject *s) {
291+
if (PyDict_Check(s))
292+
return 0;
293+
return s->ob_type->tp_as_sequence && s->ob_type->tp_as_sequence->sq_item != NULL;
294+
}
295+
296+
UPCALL_ID(PySequence_Size);
289297
Py_ssize_t PySequence_Size(PyObject *s) {
290-
return UPCALL_CEXT_L(_jls_PyObject_Size, native_to_java(s));
298+
return UPCALL_CEXT_L(_jls_PySequence_Size, native_to_java(s));
299+
}
300+
301+
// downcall for native python objects
302+
// taken from CPython "Objects/abstract.c/Py_Sequence_Size"
303+
Py_ssize_t PyTruffle_PySequence_Size(PyObject *s) {
304+
PySequenceMethods *m;
305+
306+
if (s == NULL) {
307+
null_error();
308+
return -1;
309+
}
310+
311+
m = s->ob_type->tp_as_sequence;
312+
if (m && m->sq_length) {
313+
Py_ssize_t len = m->sq_length(s);
314+
assert(len >= 0 || PyErr_Occurred());
315+
return len;
316+
}
317+
318+
if (s->ob_type->tp_as_mapping && s->ob_type->tp_as_mapping->mp_length) {
319+
PyErr_Format(PyExc_TypeError, "PyTruffle_PySequence_Size(): object of type '%s' is not a sequence", Py_TYPE(s)->tp_name);
320+
return -1;
321+
}
322+
PyErr_Format(PyExc_TypeError, "PyTruffle_PySequence_Size(): object of type '%s' has no len()", Py_TYPE(s)->tp_name);
323+
return -1;
291324
}
292325

293326
UPCALL_ID(PySequence_Contains);
@@ -347,10 +380,31 @@ PyObject * PyMapping_GetItemString(PyObject *o, const char *key) {
347380
return _jls_PyObject_GetItem(native_to_java(o), polyglot_from_string(key, SRC_CS));
348381
}
349382

383+
UPCALL_ID(PyObject_Size);
350384
Py_ssize_t PyObject_Size(PyObject *o) {
351385
return UPCALL_CEXT_L(_jls_PyObject_Size, native_to_java(o));
352386
}
353387

388+
// downcall for native python objects
389+
// taken from CPython "Objects/abstract.c/PyObject_Size"
390+
Py_ssize_t PyTruffle_PyObject_Size(PyObject *o) {
391+
PySequenceMethods *m;
392+
393+
if (o == NULL) {
394+
null_error();
395+
return -1;
396+
}
397+
398+
m = o->ob_type->tp_as_sequence;
399+
if (m && m->sq_length) {
400+
Py_ssize_t len = m->sq_length(o);
401+
assert(len >= 0 || PyErr_Occurred());
402+
return len;
403+
}
404+
405+
return PyMapping_Size(o);
406+
}
407+
354408
UPCALL_ID(PyMapping_Keys);
355409
PyObject * PyMapping_Keys(PyObject *o) {
356410
return UPCALL_CEXT_O(_jls_PyMapping_Keys, native_to_java(o));
@@ -369,8 +423,14 @@ PyObject * PyMapping_Values(PyObject *o) {
369423
return UPCALL_CEXT_O(_jls_PyMapping_Values, native_to_java(o));
370424
}
371425

372-
// taken from CPython "Objects/abstract.c"
426+
UPCALL_ID(PyMapping_Check);
373427
int PyMapping_Check(PyObject *o) {
428+
return UPCALL_CEXT_I(_jls_PyMapping_Check, native_to_java(o));
429+
}
430+
431+
// downcall for native python objects
432+
// taken from CPython "Objects/abstract.c PyMapping_Check"
433+
int PyTruffle_PyMapping_Check(PyObject *o) {
374434
return o && o->ob_type->tp_as_mapping && o->ob_type->tp_as_mapping->mp_subscript;
375435
}
376436

@@ -521,8 +581,14 @@ int PyBuffer_IsContiguous(const Py_buffer *view, char order) {
521581
return 0;
522582
}
523583

524-
// partially taken from CPython "Objects/abstract.c"
525-
Py_ssize_t PyMapping_Size(PyObject *o) {
584+
UPCALL_ID(PyMapping_Size);
585+
Py_ssize_t PyMapping_Size(PyObject *s) {
586+
return UPCALL_CEXT_L(_jls_PyMapping_Size, native_to_java(s));
587+
}
588+
589+
// PyMapping_Size downcall for native python objects
590+
// partially taken from CPython "Objects/abstract.c/Py_Mapping_Size"
591+
Py_ssize_t PyTruffle_PyMapping_Size(PyObject *o) {
526592
PyMappingMethods *m;
527593

528594
if (o == NULL) {
@@ -537,7 +603,7 @@ Py_ssize_t PyMapping_Size(PyObject *o) {
537603
return len;
538604
}
539605

540-
PyErr_Format(PyExc_TypeError, "object of type '%s' has no len()", Py_TYPE(o)->tp_name);
606+
PyErr_Format(PyExc_TypeError, "PyTruffle_PyMapping_Size(): object of type '%s' has no len()", Py_TYPE(o)->tp_name);
541607
return -1;
542608
}
543609

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

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved.
1+
# Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
22
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
33
#
44
# The Universal Permissive License (UPL), Version 1.0
@@ -516,6 +516,18 @@ def CPyExtType(name, code, **kwargs):
516516
""" if sys.version_info.minor >= 6 else "") + """
517517
}};
518518
519+
static PySequenceMethods {name}_sequence_methods = {{
520+
{sq_length}, /* sq_length */
521+
0, /* sq_concat */
522+
0, /* sq_repeat */
523+
{sq_item}, /* sq_item */
524+
}};
525+
526+
static PyMappingMethods {name}_mapping_methods = {{
527+
{mp_length}, /* mp_length */
528+
{mp_subscript}, /* mp_subscript */
529+
}};
530+
519531
static struct PyMethodDef {name}_methods[] = {{
520532
{tp_methods},
521533
{{NULL, NULL, 0, NULL}}
@@ -533,8 +545,8 @@ def CPyExtType(name, code, **kwargs):
533545
0, /* tp_reserved */
534546
{tp_repr},
535547
&{name}_number_methods,
536-
{tp_as_sequence},
537-
{tp_as_mapping},
548+
&{name}_sequence_methods,
549+
&{name}_mapping_methods,
538550
{tp_hash},
539551
{tp_call},
540552
{tp_str},

0 commit comments

Comments
 (0)