Skip to content

gh-89653: PEP 670: Convert macros to functions #99843

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Nov 28, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 24 additions & 10 deletions Include/cpython/classobject.h
Original file line number Diff line number Diff line change
@@ -26,12 +26,20 @@ PyAPI_FUNC(PyObject *) PyMethod_New(PyObject *, PyObject *);
PyAPI_FUNC(PyObject *) PyMethod_Function(PyObject *);
PyAPI_FUNC(PyObject *) PyMethod_Self(PyObject *);

/* Macros for direct access to these values. Type checks are *not*
done, so use with care. */
#define PyMethod_GET_FUNCTION(meth) \
(((PyMethodObject *)(meth)) -> im_func)
#define PyMethod_GET_SELF(meth) \
(((PyMethodObject *)(meth)) -> im_self)
#define _PyMethod_CAST(meth) \
(assert(PyMethod_Check(meth)), _Py_CAST(PyMethodObject*, meth))

/* Static inline functions for direct access to these values.
Type checks are *not* done, so use with care. */
static inline PyObject* PyMethod_GET_FUNCTION(PyObject *meth) {
return _PyMethod_CAST(meth)->im_func;
}
#define PyMethod_GET_FUNCTION(meth) PyMethod_GET_FUNCTION(_PyObject_CAST(meth))

static inline PyObject* PyMethod_GET_SELF(PyObject *meth) {
return _PyMethod_CAST(meth)->im_self;
}
#define PyMethod_GET_SELF(meth) PyMethod_GET_SELF(_PyObject_CAST(meth))

typedef struct {
PyObject_HEAD
@@ -45,10 +53,16 @@ PyAPI_DATA(PyTypeObject) PyInstanceMethod_Type;
PyAPI_FUNC(PyObject *) PyInstanceMethod_New(PyObject *);
PyAPI_FUNC(PyObject *) PyInstanceMethod_Function(PyObject *);

/* Macros for direct access to these values. Type checks are *not*
done, so use with care. */
#define PyInstanceMethod_GET_FUNCTION(meth) \
(((PyInstanceMethodObject *)(meth)) -> func)
#define _PyInstanceMethod_CAST(meth) \
(assert(PyInstanceMethod_Check(meth)), \
_Py_CAST(PyInstanceMethodObject*, meth))

/* Static inline function for direct access to these values.
Type checks are *not* done, so use with care. */
static inline PyObject* PyInstanceMethod_GET_FUNCTION(PyObject *meth) {
return _PyInstanceMethod_CAST(meth)->func;
}
#define PyInstanceMethod_GET_FUNCTION(meth) PyInstanceMethod_GET_FUNCTION(_PyObject_CAST(meth))

#ifdef __cplusplus
}
7 changes: 6 additions & 1 deletion Include/cpython/code.h
Original file line number Diff line number Diff line change
@@ -147,7 +147,12 @@ struct PyCodeObject _PyCode_DEF(1);
PyAPI_DATA(PyTypeObject) PyCode_Type;

#define PyCode_Check(op) Py_IS_TYPE((op), &PyCode_Type)
#define PyCode_GetNumFree(op) ((op)->co_nfreevars)

static inline Py_ssize_t PyCode_GetNumFree(PyCodeObject *op) {
assert(PyCode_Check(op));
return op->co_nfreevars;
}

#define _PyCode_CODE(CO) ((_Py_CODEUNIT *)(CO)->co_code_adaptive)
#define _PyCode_NBYTES(CO) (Py_SIZE(CO) * (Py_ssize_t)sizeof(_Py_CODEUNIT))

10 changes: 8 additions & 2 deletions Include/cpython/floatobject.h
Original file line number Diff line number Diff line change
@@ -7,9 +7,15 @@ typedef struct {
double ob_fval;
} PyFloatObject;

// Macro version of PyFloat_AsDouble() trading safety for speed.
#define _PyFloat_CAST(op) \
(assert(PyFloat_Check(op)), _Py_CAST(PyFloatObject*, op))

// Static inline version of PyFloat_AsDouble() trading safety for speed.
// It doesn't check if op is a double object.
#define PyFloat_AS_DOUBLE(op) (((PyFloatObject *)(op))->ob_fval)
static inline double PyFloat_AS_DOUBLE(PyObject *op) {
return _PyFloat_CAST(op)->ob_fval;
}
#define PyFloat_AS_DOUBLE(op) PyFloat_AS_DOUBLE(_PyObject_CAST(op))


PyAPI_FUNC(int) PyFloat_Pack2(double x, char *p, int le);
13 changes: 11 additions & 2 deletions Include/cpython/memoryobject.h
Original file line number Diff line number Diff line change
@@ -36,7 +36,16 @@ typedef struct {
Py_ssize_t ob_array[1]; /* shape, strides, suboffsets */
} PyMemoryViewObject;

#define _PyMemoryView_CAST(op) _Py_CAST(PyMemoryViewObject*, op)

/* Get a pointer to the memoryview's private copy of the exporter's buffer. */
#define PyMemoryView_GET_BUFFER(op) (&((PyMemoryViewObject *)(op))->view)
static inline Py_buffer* PyMemoryView_GET_BUFFER(PyObject *op) {
return (&_PyMemoryView_CAST(op)->view);
}
#define PyMemoryView_GET_BUFFER(op) PyMemoryView_GET_BUFFER(_PyObject_CAST(op))

/* Get a pointer to the exporting object (this may be NULL!). */
#define PyMemoryView_GET_BASE(op) (((PyMemoryViewObject *)(op))->view.obj)
static inline PyObject* PyMemoryView_GET_BASE(PyObject *op) {
return _PyMemoryView_CAST(op)->view.obj;
}
#define PyMemoryView_GET_BASE(op) PyMemoryView_GET_BASE(_PyObject_CAST(op))
9 changes: 7 additions & 2 deletions Include/cpython/setobject.h
Original file line number Diff line number Diff line change
@@ -58,8 +58,13 @@ typedef struct {
PyObject *weakreflist; /* List of weak references */
} PySetObject;

#define PySet_GET_SIZE(so) \
(assert(PyAnySet_Check(so)), (((PySetObject *)(so))->used))
#define _PySet_CAST(so) \
(assert(PyAnySet_Check(so)), _Py_CAST(PySetObject*, so))

static inline Py_ssize_t PySet_GET_SIZE(PyObject *so) {
return _PySet_CAST(so)->used;
}
#define PySet_GET_SIZE(so) PySet_GET_SIZE(_PyObject_CAST(so))

PyAPI_DATA(PyObject *) _PySet_Dummy;

2 changes: 0 additions & 2 deletions Include/cpython/unicodeobject.h
Original file line number Diff line number Diff line change
@@ -231,8 +231,6 @@ enum PyUnicode_Kind {
// new compiler warnings on "kind < PyUnicode_KIND(str)" (compare signed and
// unsigned numbers) where kind type is an int or on
// "unsigned int kind = PyUnicode_KIND(str)" (cast signed to unsigned).
// Only declare the function as static inline function in the limited C API
// version 3.12 which is stricter.
#define PyUnicode_KIND(op) (_PyASCIIObject_CAST(op)->state.kind)

/* Return a void pointer to the raw unicode buffer. */
21 changes: 15 additions & 6 deletions Include/internal/pycore_dict.h
Original file line number Diff line number Diff line change
@@ -128,12 +128,21 @@ struct _dictvalues {
#else
#define DK_SIZE(dk) (1<<DK_LOG_SIZE(dk))
#endif
#define DK_ENTRIES(dk) \
(assert((dk)->dk_kind == DICT_KEYS_GENERAL), \
(PyDictKeyEntry*)(&((int8_t*)((dk)->dk_indices))[(size_t)1 << (dk)->dk_log2_index_bytes]))
#define DK_UNICODE_ENTRIES(dk) \
(assert((dk)->dk_kind != DICT_KEYS_GENERAL), \
(PyDictUnicodeEntry*)(&((int8_t*)((dk)->dk_indices))[(size_t)1 << (dk)->dk_log2_index_bytes]))

static inline void* _DK_ENTRIES(PyDictKeysObject *dk) {
int8_t *indices = (int8_t*)(dk->dk_indices);
size_t index = (size_t)1 << dk->dk_log2_index_bytes;
return (&indices[index]);
}
static inline PyDictKeyEntry* DK_ENTRIES(PyDictKeysObject *dk) {
assert(dk->dk_kind == DICT_KEYS_GENERAL);
return (PyDictKeyEntry*)_DK_ENTRIES(dk);
}
static inline PyDictUnicodeEntry* DK_UNICODE_ENTRIES(PyDictKeysObject *dk) {
assert(dk->dk_kind != DICT_KEYS_GENERAL);
return (PyDictUnicodeEntry*)_DK_ENTRIES(dk);
}

#define DK_IS_UNICODE(dk) ((dk)->dk_kind != DICT_KEYS_GENERAL)

#define DICT_VERSION_INCREMENT (1 << DICT_MAX_WATCHERS)
5 changes: 3 additions & 2 deletions Include/internal/pycore_object.h
Original file line number Diff line number Diff line change
@@ -355,8 +355,9 @@ extern int _PyType_HasSubclasses(PyTypeObject *);
extern PyObject* _PyType_GetSubclasses(PyTypeObject *);

// Access macro to the members which are floating "behind" the object
#define _PyHeapType_GET_MEMBERS(etype) \
((PyMemberDef *)(((char *)(etype)) + Py_TYPE(etype)->tp_basicsize))
static inline PyMemberDef* _PyHeapType_GET_MEMBERS(PyHeapTypeObject *etype) {
return (PyMemberDef*)((char*)etype + Py_TYPE(etype)->tp_basicsize);
}

PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, PyObject *);