@@ -125,39 +125,15 @@ int PyObject_GenericInit(PyObject* self, PyObject* args, PyObject* kwds) {
125
125
return self ;
126
126
}
127
127
128
- #define IS_SINGLE_ARG (_fmt ) ((_fmt[0]) != '\0' && (_fmt[1]) == '\0')
129
-
130
- PyObject * PyObject_Call (PyObject * callable , PyObject * args , PyObject * kwargs ) {
131
- return Graal_PyTruffleObject_Call1 (callable , args , kwargs , 0 );
132
- }
133
-
134
- PyObject * PyObject_CallObject (PyObject * callable , PyObject * args ) {
135
- return Graal_PyTruffleObject_Call1 (callable , args , NULL , 0 );
136
- }
137
-
138
- PyObject * PyObject_CallFunction (PyObject * callable , const char * fmt , ...) {
139
- if (fmt == NULL || fmt [0 ] == '\0' ) {
140
- return Graal_PyTruffleObject_Call1 (callable , NULL , NULL , 0 );
141
- }
142
- va_list va ;
143
- va_start (va , fmt );
144
- PyObject * args = Py_VaBuildValue (fmt , va );
145
- va_end (va );
146
- return Graal_PyTruffleObject_Call1 (callable , args , NULL , IS_SINGLE_ARG (fmt ));
147
- }
148
-
149
- PyObject * _PyObject_CallFunction_SizeT (PyObject * callable , const char * fmt , ...) {
150
- if (fmt == NULL || fmt [0 ] == '\0' ) {
151
- return Graal_PyTruffleObject_Call1 (callable , NULL , NULL , 0 );
152
- }
153
- va_list va ;
154
- va_start (va , fmt );
155
- PyObject * args = Py_VaBuildValue (fmt , va );
156
- va_end (va );
157
- return Graal_PyTruffleObject_Call1 (callable , args , NULL , IS_SINGLE_ARG (fmt ));
128
+ PyObject * _PyObject_CallMethodIdObjArgs (PyObject * callable , struct _Py_Identifier * name , ...) {
129
+ va_list vargs ;
130
+ va_start (vargs , name );
131
+ // the arguments are given as a variable list followed by NULL
132
+ PyObject * result = GraalPyTruffleObject_CallMethodObjArgs (callable , _PyUnicode_FromId (name ), & vargs );
133
+ va_end (vargs );
134
+ return result ;
158
135
}
159
136
160
- typedef PyObject * (* call_fun_obj_args_t )(PyObject * , void * );
161
137
PyObject * PyObject_CallFunctionObjArgs (PyObject * callable , ...) {
162
138
va_list vargs ;
163
139
va_start (vargs , callable );
@@ -167,20 +143,6 @@ PyObject* PyObject_CallFunctionObjArgs(PyObject *callable, ...) {
167
143
return result ;
168
144
}
169
145
170
- typedef PyObject * (* call_method_t )(PyObject * , void * , void * , int32_t );
171
- PyObject * PyObject_CallMethod (PyObject * object , const char * method , const char * fmt , ...) {
172
- PyObject * args ;
173
- if (fmt == NULL || fmt [0 ] == '\0' ) {
174
- return Graal_PyTruffleObject_CallMethod1 (object , truffleString (method ), NULL , 0 );
175
- }
176
- va_list va ;
177
- va_start (va , fmt );
178
- args = Py_VaBuildValue (fmt , va );
179
- va_end (va );
180
- return Graal_PyTruffleObject_CallMethod1 (object , truffleString (method ), args , IS_SINGLE_ARG (fmt ));
181
- }
182
-
183
- typedef PyObject * (* call_meth_obj_args_t )(PyObject * , void * , void * );
184
146
PyObject * PyObject_CallMethodObjArgs (PyObject * callable , PyObject * name , ...) {
185
147
va_list vargs ;
186
148
va_start (vargs , name );
@@ -190,18 +152,6 @@ PyObject* PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...) {
190
152
return result ;
191
153
}
192
154
193
- PyObject * _PyObject_CallMethod_SizeT (PyObject * object , const char * method , const char * fmt , ...) {
194
- PyObject * args ;
195
- if (fmt == NULL || fmt [0 ] == '\0' ) {
196
- return Graal_PyTruffleObject_CallMethod1 (object , truffleString (method ), NULL , 0 );
197
- }
198
- va_list va ;
199
- va_start (va , fmt );
200
- args = Py_VaBuildValue (fmt , va );
201
- va_end (va );
202
- return Graal_PyTruffleObject_CallMethod1 (object , truffleString (method ), args , IS_SINGLE_ARG (fmt ));
203
- }
204
-
205
155
PyObject * _PyObject_MakeTpCall (PyThreadState * tstate , PyObject * callable ,
206
156
PyObject * const * args , Py_ssize_t nargs ,
207
157
PyObject * keywords ) {
@@ -345,6 +295,98 @@ PyObject* PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwarg
345
295
return result ;
346
296
}
347
297
298
+
299
+ // Taken from cpython object.c
300
+ /* Specialized version of _PyObject_GenericGetAttrWithDict
301
+ specifically for the LOAD_METHOD opcode.
302
+
303
+ Return 1 if a method is found, 0 if it's a regular attribute
304
+ from __dict__ or something returned by using a descriptor
305
+ protocol.
306
+
307
+ `method` will point to the resolved attribute or NULL. In the
308
+ latter case, an error will be set.
309
+ */
310
+ int
311
+ _PyObject_GetMethod (PyObject * obj , PyObject * name , PyObject * * method )
312
+ {
313
+ PyTypeObject * tp = Py_TYPE (obj );
314
+ PyObject * descr ;
315
+ descrgetfunc f = NULL ;
316
+ PyObject * * dictptr , * dict ;
317
+ PyObject * attr ;
318
+ int meth_found = 0 ;
319
+
320
+ assert (* method == NULL );
321
+
322
+ if (Py_TYPE (obj )-> tp_getattro != PyObject_GenericGetAttr
323
+ || !PyUnicode_Check (name )) {
324
+ * method = PyObject_GetAttr (obj , name );
325
+ return 0 ;
326
+ }
327
+
328
+ if (tp -> tp_dict == NULL && PyType_Ready (tp ) < 0 )
329
+ return 0 ;
330
+
331
+ descr = _PyType_Lookup (tp , name );
332
+ if (descr != NULL ) {
333
+ Py_INCREF (descr );
334
+ if (_PyType_HasFeature (Py_TYPE (descr ), Py_TPFLAGS_METHOD_DESCRIPTOR )) {
335
+ meth_found = 1 ;
336
+ } else {
337
+ f = Py_TYPE (descr )-> tp_descr_get ;
338
+ if (f != NULL && PyDescr_IsData (descr )) {
339
+ * method = f (descr , obj , (PyObject * )Py_TYPE (obj ));
340
+ Py_DECREF (descr );
341
+ return 0 ;
342
+ }
343
+ }
344
+ }
345
+
346
+ dictptr = _PyObject_GetDictPtr (obj );
347
+ if (dictptr != NULL && (dict = * dictptr ) != NULL ) {
348
+ Py_INCREF (dict );
349
+ attr = PyDict_GetItemWithError (dict , name );
350
+ if (attr != NULL ) {
351
+ Py_INCREF (attr );
352
+ * method = attr ;
353
+ Py_DECREF (dict );
354
+ Py_XDECREF (descr );
355
+ return 0 ;
356
+ }
357
+ else {
358
+ Py_DECREF (dict );
359
+ if (PyErr_Occurred ()) {
360
+ Py_XDECREF (descr );
361
+ return 0 ;
362
+ }
363
+ }
364
+ }
365
+
366
+ if (meth_found ) {
367
+ * method = descr ;
368
+ return 1 ;
369
+ }
370
+
371
+ if (f != NULL ) {
372
+ * method = f (descr , obj , (PyObject * )Py_TYPE (obj ));
373
+ Py_DECREF (descr );
374
+ return 0 ;
375
+ }
376
+
377
+ if (descr != NULL ) {
378
+ * method = descr ;
379
+ return 0 ;
380
+ }
381
+
382
+ PyErr_Format (PyExc_AttributeError ,
383
+ "'%.50s' object has no attribute '%U'" ,
384
+ tp -> tp_name , name );
385
+
386
+ // set_attribute_error_context(obj, name);
387
+ return 0 ;
388
+ }
389
+
348
390
// Taken from cpython call.c
349
391
PyObject * PyObject_VectorcallDict (PyObject * callable , PyObject * const * args ,
350
392
size_t nargsf , PyObject * kwargs ) {
@@ -380,6 +422,41 @@ PyObject* PyObject_VectorcallDict(PyObject *callable, PyObject *const *args,
380
422
return res ;
381
423
}
382
424
425
+ // Taken from cpython call.c
426
+ PyObject *
427
+ PyObject_VectorcallMethod (PyObject * name , PyObject * const * args ,
428
+ size_t nargsf , PyObject * kwnames )
429
+ {
430
+ assert (name != NULL );
431
+ assert (args != NULL );
432
+ assert (PyVectorcall_NARGS (nargsf ) >= 1 );
433
+
434
+ PyThreadState * tstate = _PyThreadState_GET ();
435
+ PyObject * callable = NULL ;
436
+ /* Use args[0] as "self" argument */
437
+ int unbound = _PyObject_GetMethod (args [0 ], name , & callable );
438
+ if (callable == NULL ) {
439
+ return NULL ;
440
+ }
441
+
442
+ if (unbound ) {
443
+ /* We must remove PY_VECTORCALL_ARGUMENTS_OFFSET since
444
+ * that would be interpreted as allowing to change args[-1] */
445
+ nargsf &= ~PY_VECTORCALL_ARGUMENTS_OFFSET ;
446
+ }
447
+ else {
448
+ /* Skip "self". We can keep PY_VECTORCALL_ARGUMENTS_OFFSET since
449
+ * args[-1] in the onward call is args[0] here. */
450
+ args ++ ;
451
+ nargsf -- ;
452
+ }
453
+ PyObject * result = _PyObject_VectorcallTstate (tstate , callable ,
454
+ args , nargsf , kwnames );
455
+ Py_DECREF (callable );
456
+ return result ;
457
+ }
458
+
459
+
383
460
// Taken from CPython object.c
384
461
int
385
462
PyObject_GenericSetDict (PyObject * obj , PyObject * value , void * context )
0 commit comments