From dad0c57750096fc48ee86b61f3225e1a0312bcaa Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 24 Aug 2021 15:50:34 +0200 Subject: [PATCH 1/3] Offset arguments for PyObject_Vectorcall in the _sqlite module This allows e.g. methods to be called efficiently by providing space for a "self" argument; see PY_VECTORCALL_ARGUMENTS_OFFSET docs. --- Modules/_sqlite/connection.c | 19 +++++++++++-------- Modules/_sqlite/cursor.c | 5 +++-- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 8ad5f5f061da5d..a903b27cefbc95 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -59,19 +59,21 @@ static void _pysqlite_drop_unused_cursor_references(pysqlite_Connection* self); static PyObject * new_statement_cache(pysqlite_Connection *self, int maxsize) { - PyObject *args[] = { PyLong_FromLong(maxsize), }; - if (args[0] == NULL) { + PyObject *args[] = { NULL, PyLong_FromLong(maxsize), }; + if (args[1] == NULL) { return NULL; } PyObject *lru_cache = self->state->lru_cache; - PyObject *inner = PyObject_Vectorcall(lru_cache, args, 1, NULL); - Py_DECREF(args[0]); + PyObject *inner = PyObject_Vectorcall( + lru_cache, args + 1, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + Py_DECREF(args[1]); if (inner == NULL) { return NULL; } - args[0] = (PyObject *)self; // Borrowed ref. - PyObject *res = PyObject_Vectorcall(inner, args, 1, NULL); + args[1] = (PyObject *)self; // Borrowed ref. + PyObject *res = PyObject_Vectorcall( + inner, args + 1, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); Py_DECREF(inner); return res; } @@ -1482,8 +1484,9 @@ pysqlite_collation_callback( callback_context *ctx = (callback_context *)context; assert(ctx != NULL); - PyObject *args[] = { string1, string2 }; // Borrowed refs. - retval = PyObject_Vectorcall(ctx->callable, args, 2, NULL); + PyObject *args[] = { NULL, string1, string2 }; // Borrowed refs. + retval = PyObject_Vectorcall( + ctx->callable, args + 1, 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); if (retval == NULL) { /* execution failed */ goto finally; diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index e418cafb4feb60..a39e566cffcc2c 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -465,9 +465,10 @@ begin_transaction(pysqlite_Connection *self) static PyObject * get_statement_from_cache(pysqlite_Cursor *self, PyObject *operation) { - PyObject *args[] = { operation, }; + PyObject *args[] = { NULL, operation, }; PyObject *cache = self->connection->statement_cache; - return PyObject_Vectorcall(cache, args, 1, NULL); + return PyObject_Vectorcall( + cache, args + 1, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); } static PyObject * From 2cbaf4d029c6147eb1502e68db457cdbfd841773 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 31 Aug 2021 13:54:26 +0200 Subject: [PATCH 2/3] Note about borrowed ref --- Modules/_sqlite/cursor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index a39e566cffcc2c..4a617f24d539b0 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -465,7 +465,7 @@ begin_transaction(pysqlite_Connection *self) static PyObject * get_statement_from_cache(pysqlite_Cursor *self, PyObject *operation) { - PyObject *args[] = { NULL, operation, }; + PyObject *args[] = { NULL, operation, }; // Borrowed ref. PyObject *cache = self->connection->statement_cache; return PyObject_Vectorcall( cache, args + 1, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); From 3a2e3fac62d3b4e94809073721079b59eb642474 Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 31 Aug 2021 13:57:14 +0200 Subject: [PATCH 3/3] Avoid long lines --- Modules/_sqlite/connection.c | 12 ++++++------ Modules/_sqlite/cursor.c | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index a903b27cefbc95..ba784b79950d00 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -64,16 +64,16 @@ new_statement_cache(pysqlite_Connection *self, int maxsize) return NULL; } PyObject *lru_cache = self->state->lru_cache; - PyObject *inner = PyObject_Vectorcall( - lru_cache, args + 1, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; + PyObject *inner = PyObject_Vectorcall(lru_cache, args + 1, nargsf, NULL); Py_DECREF(args[1]); if (inner == NULL) { return NULL; } args[1] = (PyObject *)self; // Borrowed ref. - PyObject *res = PyObject_Vectorcall( - inner, args + 1, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; + PyObject *res = PyObject_Vectorcall(inner, args + 1, nargsf, NULL); Py_DECREF(inner); return res; } @@ -1485,8 +1485,8 @@ pysqlite_collation_callback( callback_context *ctx = (callback_context *)context; assert(ctx != NULL); PyObject *args[] = { NULL, string1, string2 }; // Borrowed refs. - retval = PyObject_Vectorcall( - ctx->callable, args + 1, 2 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET; + retval = PyObject_Vectorcall(ctx->callable, args + 1, nargsf, NULL); if (retval == NULL) { /* execution failed */ goto finally; diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 4a617f24d539b0..b5864c5a632fd5 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -467,8 +467,8 @@ get_statement_from_cache(pysqlite_Cursor *self, PyObject *operation) { PyObject *args[] = { NULL, operation, }; // Borrowed ref. PyObject *cache = self->connection->statement_cache; - return PyObject_Vectorcall( - cache, args + 1, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; + return PyObject_Vectorcall(cache, args + 1, nargsf, NULL); } static PyObject *