@@ -1440,16 +1440,19 @@ lookup_method(PyObject *self, _Py_Identifier *attrid, int *unbound)
1440
1440
return res ;
1441
1441
}
1442
1442
1443
- static PyObject *
1444
- call_unbound (int unbound , PyObject * func , PyObject * self ,
1445
- PyObject * * args , Py_ssize_t nargs )
1443
+
1444
+ static inline PyObject *
1445
+ vectorcall_unbound (int unbound , PyObject * func ,
1446
+ PyObject * const * args , Py_ssize_t nargs )
1446
1447
{
1447
- if (unbound ) {
1448
- return _PyObject_FastCall_Prepend (func , self , args , nargs );
1449
- }
1450
- else {
1451
- return _PyObject_FastCall (func , args , nargs );
1448
+ size_t nargsf = nargs ;
1449
+ if (!unbound ) {
1450
+ /* Skip self argument, freeing up args[0] to use for
1451
+ * PY_VECTORCALL_ARGUMENTS_OFFSET */
1452
+ args ++ ;
1453
+ nargsf = nargsf - 1 + PY_VECTORCALL_ARGUMENTS_OFFSET ;
1452
1454
}
1455
+ return _PyObject_Vectorcall (func , args , nargsf , NULL );
1453
1456
}
1454
1457
1455
1458
static PyObject *
@@ -1464,41 +1467,43 @@ call_unbound_noarg(int unbound, PyObject *func, PyObject *self)
1464
1467
}
1465
1468
}
1466
1469
1467
- /* A variation of PyObject_CallMethod* that uses lookup_maybe_method()
1468
- instead of PyObject_GetAttrString(). */
1470
+ /* A variation of PyObject_CallMethod* that uses lookup_method()
1471
+ instead of PyObject_GetAttrString().
1472
+
1473
+ args is an argument vector of length nargs. The first element in this
1474
+ vector is the special object "self" which is used for the method lookup */
1469
1475
static PyObject *
1470
- call_method ( PyObject * obj , _Py_Identifier * name ,
1471
- PyObject * * args , Py_ssize_t nargs )
1476
+ vectorcall_method ( _Py_Identifier * name ,
1477
+ PyObject * const * args , Py_ssize_t nargs )
1472
1478
{
1479
+ assert (nargs >= 1 );
1473
1480
int unbound ;
1474
- PyObject * func , * retval ;
1475
-
1476
- func = lookup_method (obj , name , & unbound );
1481
+ PyObject * self = args [0 ];
1482
+ PyObject * func = lookup_method (self , name , & unbound );
1477
1483
if (func == NULL ) {
1478
1484
return NULL ;
1479
1485
}
1480
- retval = call_unbound (unbound , func , obj , args , nargs );
1486
+ PyObject * retval = vectorcall_unbound (unbound , func , args , nargs );
1481
1487
Py_DECREF (func );
1482
1488
return retval ;
1483
1489
}
1484
1490
1485
- /* Clone of call_method () that returns NotImplemented when the lookup fails. */
1486
-
1491
+ /* Clone of vectorcall_method () that returns NotImplemented
1492
+ * when the lookup fails. */
1487
1493
static PyObject *
1488
- call_maybe ( PyObject * obj , _Py_Identifier * name ,
1489
- PyObject * * args , Py_ssize_t nargs )
1494
+ vectorcall_maybe ( _Py_Identifier * name ,
1495
+ PyObject * const * args , Py_ssize_t nargs )
1490
1496
{
1497
+ assert (nargs >= 1 );
1491
1498
int unbound ;
1492
- PyObject * func , * retval ;
1493
-
1494
- func = lookup_maybe_method (obj , name , & unbound );
1499
+ PyObject * self = args [0 ];
1500
+ PyObject * func = lookup_maybe_method (self , name , & unbound );
1495
1501
if (func == NULL ) {
1496
1502
if (!PyErr_Occurred ())
1497
1503
Py_RETURN_NOTIMPLEMENTED ;
1498
1504
return NULL ;
1499
1505
}
1500
-
1501
- retval = call_unbound (unbound , func , obj , args , nargs );
1506
+ PyObject * retval = vectorcall_unbound (unbound , func , args , nargs );
1502
1507
Py_DECREF (func );
1503
1508
return retval ;
1504
1509
}
@@ -6084,17 +6089,18 @@ add_tp_new_wrapper(PyTypeObject *type)
6084
6089
static PyObject * \
6085
6090
FUNCNAME(PyObject *self) \
6086
6091
{ \
6092
+ PyObject* stack[1] = {self}; \
6087
6093
_Py_static_string(id, OPSTR); \
6088
- return call_method(self, &id, NULL, 0 ); \
6094
+ return vectorcall_method( &id, stack, 1 ); \
6089
6095
}
6090
6096
6091
6097
#define SLOT1 (FUNCNAME , OPSTR , ARG1TYPE ) \
6092
6098
static PyObject * \
6093
6099
FUNCNAME(PyObject *self, ARG1TYPE arg1) \
6094
6100
{ \
6095
- PyObject* stack[1 ] = {arg1}; \
6101
+ PyObject* stack[2 ] = {self, arg1}; \
6096
6102
_Py_static_string(id, OPSTR); \
6097
- return call_method(self, &id, stack, 1 ); \
6103
+ return vectorcall_method( &id, stack, 2 ); \
6098
6104
}
6099
6105
6100
6106
/* Boolean helper for SLOT1BINFULL().
@@ -6136,7 +6142,7 @@ method_is_overloaded(PyObject *left, PyObject *right, struct _Py_Identifier *nam
6136
6142
static PyObject * \
6137
6143
FUNCNAME(PyObject *self, PyObject *other) \
6138
6144
{ \
6139
- PyObject* stack[1 ]; \
6145
+ PyObject* stack[2 ]; \
6140
6146
_Py_static_string(op_id, OPSTR); \
6141
6147
_Py_static_string(rop_id, ROPSTR); \
6142
6148
int do_other = Py_TYPE(self) != Py_TYPE(other) && \
@@ -6148,23 +6154,26 @@ FUNCNAME(PyObject *self, PyObject *other) \
6148
6154
if (do_other && \
6149
6155
PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self)) && \
6150
6156
method_is_overloaded(self, other, &rop_id)) { \
6151
- stack[0] = self; \
6152
- r = call_maybe(other, &rop_id, stack, 1); \
6157
+ stack[0] = other; \
6158
+ stack[1] = self; \
6159
+ r = vectorcall_maybe(&rop_id, stack, 2); \
6153
6160
if (r != Py_NotImplemented) \
6154
6161
return r; \
6155
6162
Py_DECREF(r); \
6156
6163
do_other = 0; \
6157
6164
} \
6158
- stack[0] = other; \
6159
- r = call_maybe(self, &op_id, stack, 1); \
6165
+ stack[0] = self; \
6166
+ stack[1] = other; \
6167
+ r = vectorcall_maybe(&op_id, stack, 2); \
6160
6168
if (r != Py_NotImplemented || \
6161
6169
Py_TYPE(other) == Py_TYPE(self)) \
6162
6170
return r; \
6163
6171
Py_DECREF(r); \
6164
6172
} \
6165
6173
if (do_other) { \
6166
- stack[0] = self; \
6167
- return call_maybe(other, &rop_id, stack, 1); \
6174
+ stack[0] = other; \
6175
+ stack[1] = self; \
6176
+ return vectorcall_maybe(&rop_id, stack, 2); \
6168
6177
} \
6169
6178
Py_RETURN_NOTIMPLEMENTED; \
6170
6179
}
@@ -6175,7 +6184,8 @@ FUNCNAME(PyObject *self, PyObject *other) \
6175
6184
static Py_ssize_t
6176
6185
slot_sq_length (PyObject * self )
6177
6186
{
6178
- PyObject * res = call_method (self , & PyId___len__ , NULL , 0 );
6187
+ PyObject * stack [1 ] = {self };
6188
+ PyObject * res = vectorcall_method (& PyId___len__ , stack , 1 );
6179
6189
Py_ssize_t len ;
6180
6190
6181
6191
if (res == NULL )
@@ -6202,22 +6212,20 @@ slot_sq_length(PyObject *self)
6202
6212
static PyObject *
6203
6213
slot_sq_item (PyObject * self , Py_ssize_t i )
6204
6214
{
6205
- PyObject * retval ;
6206
- PyObject * args [1 ];
6207
6215
PyObject * ival = PyLong_FromSsize_t (i );
6208
6216
if (ival == NULL ) {
6209
6217
return NULL ;
6210
6218
}
6211
- args [ 0 ] = ival ;
6212
- retval = call_method ( self , & PyId___getitem__ , args , 1 );
6219
+ PyObject * stack [ 2 ] = { self , ival } ;
6220
+ PyObject * retval = vectorcall_method ( & PyId___getitem__ , stack , 2 );
6213
6221
Py_DECREF (ival );
6214
6222
return retval ;
6215
6223
}
6216
6224
6217
6225
static int
6218
6226
slot_sq_ass_item (PyObject * self , Py_ssize_t index , PyObject * value )
6219
6227
{
6220
- PyObject * stack [2 ];
6228
+ PyObject * stack [3 ];
6221
6229
PyObject * res ;
6222
6230
PyObject * index_obj ;
6223
6231
@@ -6226,13 +6234,14 @@ slot_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value)
6226
6234
return -1 ;
6227
6235
}
6228
6236
6229
- stack [0 ] = index_obj ;
6237
+ stack [0 ] = self ;
6238
+ stack [1 ] = index_obj ;
6230
6239
if (value == NULL ) {
6231
- res = call_method ( self , & PyId___delitem__ , stack , 1 );
6240
+ res = vectorcall_method ( & PyId___delitem__ , stack , 2 );
6232
6241
}
6233
6242
else {
6234
- stack [1 ] = value ;
6235
- res = call_method ( self , & PyId___setitem__ , stack , 2 );
6243
+ stack [2 ] = value ;
6244
+ res = vectorcall_method ( & PyId___setitem__ , stack , 3 );
6236
6245
}
6237
6246
Py_DECREF (index_obj );
6238
6247
@@ -6259,8 +6268,8 @@ slot_sq_contains(PyObject *self, PyObject *value)
6259
6268
return -1 ;
6260
6269
}
6261
6270
if (func != NULL ) {
6262
- PyObject * args [1 ] = {value };
6263
- res = call_unbound (unbound , func , self , args , 1 );
6271
+ PyObject * args [2 ] = {self , value };
6272
+ res = vectorcall_unbound (unbound , func , args , 2 );
6264
6273
Py_DECREF (func );
6265
6274
if (res != NULL ) {
6266
6275
result = PyObject_IsTrue (res );
@@ -6282,16 +6291,17 @@ SLOT1(slot_mp_subscript, "__getitem__", PyObject *)
6282
6291
static int
6283
6292
slot_mp_ass_subscript (PyObject * self , PyObject * key , PyObject * value )
6284
6293
{
6285
- PyObject * stack [2 ];
6294
+ PyObject * stack [3 ];
6286
6295
PyObject * res ;
6287
6296
6288
- stack [0 ] = key ;
6297
+ stack [0 ] = self ;
6298
+ stack [1 ] = key ;
6289
6299
if (value == NULL ) {
6290
- res = call_method ( self , & PyId___delitem__ , stack , 1 );
6300
+ res = vectorcall_method ( & PyId___delitem__ , stack , 2 );
6291
6301
}
6292
6302
else {
6293
- stack [1 ] = value ;
6294
- res = call_method ( self , & PyId___setitem__ , stack , 2 );
6303
+ stack [2 ] = value ;
6304
+ res = vectorcall_method ( & PyId___setitem__ , stack , 3 );
6295
6305
}
6296
6306
6297
6307
if (res == NULL )
@@ -6324,8 +6334,8 @@ slot_nb_power(PyObject *self, PyObject *other, PyObject *modulus)
6324
6334
slot_nb_power, so check before calling self.__pow__. */
6325
6335
if (Py_TYPE (self )-> tp_as_number != NULL &&
6326
6336
Py_TYPE (self )-> tp_as_number -> nb_power == slot_nb_power ) {
6327
- PyObject * stack [2 ] = {other , modulus };
6328
- return call_method ( self , & PyId___pow__ , stack , 2 );
6337
+ PyObject * stack [3 ] = {self , other , modulus };
6338
+ return vectorcall_method ( & PyId___pow__ , stack , 3 );
6329
6339
}
6330
6340
Py_RETURN_NOTIMPLEMENTED ;
6331
6341
}
@@ -6392,7 +6402,8 @@ static PyObject *
6392
6402
slot_nb_index (PyObject * self )
6393
6403
{
6394
6404
_Py_IDENTIFIER (__index__ );
6395
- return call_method (self , & PyId___index__ , NULL , 0 );
6405
+ PyObject * stack [1 ] = {self };
6406
+ return vectorcall_method (& PyId___index__ , stack , 1 );
6396
6407
}
6397
6408
6398
6409
@@ -6414,9 +6425,9 @@ SLOT1(slot_nb_inplace_remainder, "__imod__", PyObject *)
6414
6425
static PyObject *
6415
6426
slot_nb_inplace_power (PyObject * self , PyObject * arg1 , PyObject * arg2 )
6416
6427
{
6417
- PyObject * stack [1 ] = {arg1 };
6428
+ PyObject * stack [2 ] = {self , arg1 };
6418
6429
_Py_IDENTIFIER (__ipow__ );
6419
- return call_method ( self , & PyId___ipow__ , stack , 1 );
6430
+ return vectorcall_method ( & PyId___ipow__ , stack , 2 );
6420
6431
}
6421
6432
SLOT1 (slot_nb_inplace_lshift , "__ilshift__" , PyObject * )
6422
6433
SLOT1 (slot_nb_inplace_rshift , "__irshift__" , PyObject * )
@@ -6533,8 +6544,8 @@ slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds)
6533
6544
static PyObject *
6534
6545
slot_tp_getattro (PyObject * self , PyObject * name )
6535
6546
{
6536
- PyObject * stack [1 ] = {name };
6537
- return call_method ( self , & PyId___getattribute__ , stack , 1 );
6547
+ PyObject * stack [2 ] = {self , name };
6548
+ return vectorcall_method ( & PyId___getattribute__ , stack , 2 );
6538
6549
}
6539
6550
6540
6551
static PyObject *
@@ -6601,18 +6612,19 @@ slot_tp_getattr_hook(PyObject *self, PyObject *name)
6601
6612
static int
6602
6613
slot_tp_setattro (PyObject * self , PyObject * name , PyObject * value )
6603
6614
{
6604
- PyObject * stack [2 ];
6615
+ PyObject * stack [3 ];
6605
6616
PyObject * res ;
6606
6617
_Py_IDENTIFIER (__delattr__ );
6607
6618
_Py_IDENTIFIER (__setattr__ );
6608
6619
6609
- stack [0 ] = name ;
6620
+ stack [0 ] = self ;
6621
+ stack [1 ] = name ;
6610
6622
if (value == NULL ) {
6611
- res = call_method ( self , & PyId___delattr__ , stack , 1 );
6623
+ res = vectorcall_method ( & PyId___delattr__ , stack , 2 );
6612
6624
}
6613
6625
else {
6614
- stack [1 ] = value ;
6615
- res = call_method ( self , & PyId___setattr__ , stack , 2 );
6626
+ stack [2 ] = value ;
6627
+ res = vectorcall_method ( & PyId___setattr__ , stack , 3 );
6616
6628
}
6617
6629
if (res == NULL )
6618
6630
return -1 ;
@@ -6641,8 +6653,8 @@ slot_tp_richcompare(PyObject *self, PyObject *other, int op)
6641
6653
Py_RETURN_NOTIMPLEMENTED ;
6642
6654
}
6643
6655
6644
- PyObject * args [ 1 ] = {other };
6645
- res = call_unbound (unbound , func , self , args , 1 );
6656
+ PyObject * stack [ 2 ] = {self , other };
6657
+ res = vectorcall_unbound (unbound , func , stack , 2 );
6646
6658
Py_DECREF (func );
6647
6659
return res ;
6648
6660
}
@@ -6685,7 +6697,8 @@ static PyObject *
6685
6697
slot_tp_iternext (PyObject * self )
6686
6698
{
6687
6699
_Py_IDENTIFIER (__next__ );
6688
- return call_method (self , & PyId___next__ , NULL , 0 );
6700
+ PyObject * stack [1 ] = {self };
6701
+ return vectorcall_method (& PyId___next__ , stack , 1 );
6689
6702
}
6690
6703
6691
6704
static PyObject *
@@ -6713,18 +6726,19 @@ slot_tp_descr_get(PyObject *self, PyObject *obj, PyObject *type)
6713
6726
static int
6714
6727
slot_tp_descr_set (PyObject * self , PyObject * target , PyObject * value )
6715
6728
{
6716
- PyObject * stack [2 ];
6729
+ PyObject * stack [3 ];
6717
6730
PyObject * res ;
6718
6731
_Py_IDENTIFIER (__delete__ );
6719
6732
_Py_IDENTIFIER (__set__ );
6720
6733
6721
- stack [0 ] = target ;
6734
+ stack [0 ] = self ;
6735
+ stack [1 ] = target ;
6722
6736
if (value == NULL ) {
6723
- res = call_method ( self , & PyId___delete__ , stack , 1 );
6737
+ res = vectorcall_method ( & PyId___delete__ , stack , 2 );
6724
6738
}
6725
6739
else {
6726
- stack [1 ] = value ;
6727
- res = call_method ( self , & PyId___set__ , stack , 2 );
6740
+ stack [2 ] = value ;
6741
+ res = vectorcall_method ( & PyId___set__ , stack , 3 );
6728
6742
}
6729
6743
if (res == NULL )
6730
6744
return -1 ;
0 commit comments