LCOV - code coverage report
Current view: | top level - Modules/_testcapi - vectorcall_limited.c (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 6 | 71 | 8.5 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 1 | 6 | 16.7 %
|  |  | Branches: | 3 | 30 | 10.0 %

               Branch data     Line data    Source code
           1                 :            : #define Py_LIMITED_API 0x030c0000 // 3.12
           2                 :            : #include "parts.h"
           3                 :            :
           4                 :            : #ifdef LIMITED_API_AVAILABLE
           5                 :            :
           6                 :            : #include "structmember.h"         // PyMemberDef
           7                 :            :
           8                 :            : /* Test Vectorcall in the limited API */
           9                 :            :
          10                 :            : static PyObject *
          11                 :          0 : LimitedVectorCallClass_tpcall(PyObject *self, PyObject *args, PyObject *kwargs) {
          12                 :          0 :     return PyUnicode_FromString("tp_call called");
          13                 :            : }
          14                 :            :
          15                 :            : static PyObject *
          16                 :          0 : LimitedVectorCallClass_vectorcall(PyObject *callable,
          17                 :            :                             PyObject *const *args,
          18                 :            :                             size_t nargsf,
          19                 :            :                             PyObject *kwnames) {
          20                 :          0 :     return PyUnicode_FromString("vectorcall called");
          21                 :            : }
          22                 :            :
          23                 :            : static PyObject *
          24                 :          0 : LimitedVectorCallClass_new(PyTypeObject *tp, PyTypeObject *a, PyTypeObject *kw)
          25                 :            : {
          26                 :          0 :     PyObject *self = ((allocfunc)PyType_GetSlot(tp, Py_tp_alloc))(tp, 0);
          27         [ #  # ]:          0 :     if (!self) {
          28                 :          0 :         return NULL;
          29                 :            :     }
          30                 :          0 :     *(vectorcallfunc*)((char*)self + sizeof(PyObject)) = (
          31                 :            :         LimitedVectorCallClass_vectorcall);
          32                 :          0 :     return self;
          33                 :            : }
          34                 :            :
          35                 :            : static PyObject *
          36                 :          0 : call_vectorcall(PyObject* self, PyObject *callable)
          37                 :            : {
          38                 :          0 :     PyObject *args[3] = { NULL, NULL, NULL };
          39                 :          0 :     PyObject *kwname = NULL, *kwnames = NULL, *result = NULL;
          40                 :            :
          41                 :          0 :     args[1] = PyUnicode_FromString("foo");
          42         [ #  # ]:          0 :     if (!args[1]) {
          43                 :          0 :         goto leave;
          44                 :            :     }
          45                 :            :
          46                 :          0 :     args[2] = PyUnicode_FromString("bar");
          47         [ #  # ]:          0 :     if (!args[2]) {
          48                 :          0 :         goto leave;
          49                 :            :     }
          50                 :            :
          51                 :          0 :     kwname = PyUnicode_InternFromString("baz");
          52         [ #  # ]:          0 :     if (!kwname) {
          53                 :          0 :         goto leave;
          54                 :            :     }
          55                 :            :
          56                 :          0 :     kwnames = PyTuple_New(1);
          57         [ #  # ]:          0 :     if (!kwnames) {
          58                 :          0 :         goto leave;
          59                 :            :     }
          60                 :            :
          61         [ #  # ]:          0 :     if (PyTuple_SetItem(kwnames, 0, kwname)) {
          62                 :          0 :         goto leave;
          63                 :            :     }
          64                 :            :
          65                 :          0 :     result = PyObject_Vectorcall(
          66                 :            :         callable,
          67                 :            :         args + 1,
          68                 :            :         1 | PY_VECTORCALL_ARGUMENTS_OFFSET,
          69                 :            :         kwnames
          70                 :            :     );
          71                 :            :
          72                 :          0 : leave:
          73                 :          0 :     Py_XDECREF(args[1]);
          74                 :          0 :     Py_XDECREF(args[2]);
          75                 :          0 :     Py_XDECREF(kwnames);
          76                 :            :
          77                 :          0 :     return result;
          78                 :            : }
          79                 :            :
          80                 :            : static PyObject *
          81                 :          0 : call_vectorcall_method(PyObject* self, PyObject *callable)
          82                 :            : {
          83                 :          0 :     PyObject *args[3] = { NULL, NULL, NULL };
          84                 :          0 :     PyObject *name = NULL, *kwname = NULL,
          85                 :          0 :              *kwnames = NULL, *result = NULL;
          86                 :            :
          87                 :          0 :     name = PyUnicode_FromString("f");
          88         [ #  # ]:          0 :     if (!name) {
          89                 :          0 :         goto leave;
          90                 :            :     }
          91                 :            :
          92                 :          0 :     args[0] = callable;
          93                 :          0 :     args[1] = PyUnicode_FromString("foo");
          94         [ #  # ]:          0 :     if (!args[1]) {
          95                 :          0 :         goto leave;
          96                 :            :     }
          97                 :            :
          98                 :          0 :     args[2] = PyUnicode_FromString("bar");
          99         [ #  # ]:          0 :     if (!args[2]) {
         100                 :          0 :         goto leave;
         101                 :            :     }
         102                 :            :
         103                 :          0 :     kwname = PyUnicode_InternFromString("baz");
         104         [ #  # ]:          0 :     if (!kwname) {
         105                 :          0 :         goto leave;
         106                 :            :     }
         107                 :            :
         108                 :          0 :     kwnames = PyTuple_New(1);
         109         [ #  # ]:          0 :     if (!kwnames) {
         110                 :          0 :         goto leave;
         111                 :            :     }
         112                 :            :
         113         [ #  # ]:          0 :     if (PyTuple_SetItem(kwnames, 0, kwname)) {
         114                 :          0 :         goto leave;
         115                 :            :     }
         116                 :            :
         117                 :            :
         118                 :          0 :     result = PyObject_VectorcallMethod(
         119                 :            :         name,
         120                 :            :         args,
         121                 :            :         2 | PY_VECTORCALL_ARGUMENTS_OFFSET,
         122                 :            :         kwnames
         123                 :            :     );
         124                 :            :
         125                 :          0 : leave:
         126                 :          0 :     Py_XDECREF(name);
         127                 :          0 :     Py_XDECREF(args[1]);
         128                 :          0 :     Py_XDECREF(args[2]);
         129                 :          0 :     Py_XDECREF(kwnames);
         130                 :            :
         131                 :          0 :     return result;
         132                 :            : }
         133                 :            :
         134                 :            : static PyMemberDef LimitedVectorCallClass_members[] = {
         135                 :            :     {"__vectorcalloffset__", T_PYSSIZET, sizeof(PyObject), READONLY},
         136                 :            :     {NULL}
         137                 :            : };
         138                 :            :
         139                 :            : static PyType_Slot LimitedVectorallClass_slots[] = {
         140                 :            :     {Py_tp_new, LimitedVectorCallClass_new},
         141                 :            :     {Py_tp_call, LimitedVectorCallClass_tpcall},
         142                 :            :     {Py_tp_members, LimitedVectorCallClass_members},
         143                 :            :     {0},
         144                 :            : };
         145                 :            :
         146                 :            : static PyType_Spec LimitedVectorCallClass_spec = {
         147                 :            :     .name = "_testcapi.LimitedVectorCallClass",
         148                 :            :     .basicsize = (int)(sizeof(PyObject) + sizeof(vectorcallfunc)),
         149                 :            :     .flags = Py_TPFLAGS_DEFAULT
         150                 :            :         | Py_TPFLAGS_HAVE_VECTORCALL
         151                 :            :         | Py_TPFLAGS_BASETYPE,
         152                 :            :     .slots = LimitedVectorallClass_slots,
         153                 :            : };
         154                 :            :
         155                 :            : static PyMethodDef TestMethods[] = {
         156                 :            :     {"call_vectorcall", call_vectorcall, METH_O},
         157                 :            :     {"call_vectorcall_method", call_vectorcall_method, METH_O},
         158                 :            :     {NULL},
         159                 :            : };
         160                 :            :
         161                 :            : int
         162                 :          2 : _PyTestCapi_Init_VectorcallLimited(PyObject *m) {
         163         [ -  + ]:          2 :     if (PyModule_AddFunctions(m, TestMethods) < 0) {
         164                 :          0 :         return -1;
         165                 :            :     }
         166                 :            :
         167                 :          2 :     PyObject *LimitedVectorCallClass = PyType_FromModuleAndSpec(
         168                 :            :         m, &LimitedVectorCallClass_spec, NULL);
         169         [ -  + ]:          2 :     if (!LimitedVectorCallClass) {
         170                 :          0 :         return -1;
         171                 :            :     }
         172         [ -  + ]:          2 :     if (PyModule_AddType(m, (PyTypeObject *)LimitedVectorCallClass) < 0) {
         173                 :          0 :         return -1;
         174                 :            :     }
         175                 :            :
         176                 :          2 :     return 0;
         177                 :            : }
         178                 :            :
         179                 :            : #endif // LIMITED_API_AVAILABLE

Generated by: LCOV version 1.14