17db96d56Sopenharmony_ci#ifndef Py_INTERNAL_ASDL_H
27db96d56Sopenharmony_ci#define Py_INTERNAL_ASDL_H
37db96d56Sopenharmony_ci#ifdef __cplusplus
47db96d56Sopenharmony_ciextern "C" {
57db96d56Sopenharmony_ci#endif
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ci#ifndef Py_BUILD_CORE
87db96d56Sopenharmony_ci#  error "this header requires Py_BUILD_CORE define"
97db96d56Sopenharmony_ci#endif
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ci#include "pycore_pyarena.h"       // _PyArena_Malloc()
127db96d56Sopenharmony_ci
137db96d56Sopenharmony_citypedef PyObject * identifier;
147db96d56Sopenharmony_citypedef PyObject * string;
157db96d56Sopenharmony_citypedef PyObject * object;
167db96d56Sopenharmony_citypedef PyObject * constant;
177db96d56Sopenharmony_ci
187db96d56Sopenharmony_ci/* It would be nice if the code generated by asdl_c.py was completely
197db96d56Sopenharmony_ci   independent of Python, but it is a goal the requires too much work
207db96d56Sopenharmony_ci   at this stage.  So, for example, I'll represent identifiers as
217db96d56Sopenharmony_ci   interned Python strings.
227db96d56Sopenharmony_ci*/
237db96d56Sopenharmony_ci
247db96d56Sopenharmony_ci#define _ASDL_SEQ_HEAD \
257db96d56Sopenharmony_ci    Py_ssize_t size;   \
267db96d56Sopenharmony_ci    void **elements;
277db96d56Sopenharmony_ci
287db96d56Sopenharmony_citypedef struct {
297db96d56Sopenharmony_ci    _ASDL_SEQ_HEAD
307db96d56Sopenharmony_ci} asdl_seq;
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_citypedef struct {
337db96d56Sopenharmony_ci    _ASDL_SEQ_HEAD
347db96d56Sopenharmony_ci    void *typed_elements[1];
357db96d56Sopenharmony_ci} asdl_generic_seq;
367db96d56Sopenharmony_ci
377db96d56Sopenharmony_citypedef struct {
387db96d56Sopenharmony_ci    _ASDL_SEQ_HEAD
397db96d56Sopenharmony_ci    PyObject *typed_elements[1];
407db96d56Sopenharmony_ci} asdl_identifier_seq;
417db96d56Sopenharmony_ci
427db96d56Sopenharmony_citypedef struct {
437db96d56Sopenharmony_ci    _ASDL_SEQ_HEAD
447db96d56Sopenharmony_ci    int typed_elements[1];
457db96d56Sopenharmony_ci} asdl_int_seq;
467db96d56Sopenharmony_ci
477db96d56Sopenharmony_ciasdl_generic_seq *_Py_asdl_generic_seq_new(Py_ssize_t size, PyArena *arena);
487db96d56Sopenharmony_ciasdl_identifier_seq *_Py_asdl_identifier_seq_new(Py_ssize_t size, PyArena *arena);
497db96d56Sopenharmony_ciasdl_int_seq *_Py_asdl_int_seq_new(Py_ssize_t size, PyArena *arena);
507db96d56Sopenharmony_ci
517db96d56Sopenharmony_ci
527db96d56Sopenharmony_ci#define GENERATE_ASDL_SEQ_CONSTRUCTOR(NAME, TYPE) \
537db96d56Sopenharmony_ciasdl_ ## NAME ## _seq *_Py_asdl_ ## NAME ## _seq_new(Py_ssize_t size, PyArena *arena) \
547db96d56Sopenharmony_ci{ \
557db96d56Sopenharmony_ci    asdl_ ## NAME ## _seq *seq = NULL; \
567db96d56Sopenharmony_ci    size_t n; \
577db96d56Sopenharmony_ci    /* check size is sane */ \
587db96d56Sopenharmony_ci    if (size < 0 || \
597db96d56Sopenharmony_ci        (size && (((size_t)size - 1) > (SIZE_MAX / sizeof(void *))))) { \
607db96d56Sopenharmony_ci        PyErr_NoMemory(); \
617db96d56Sopenharmony_ci        return NULL; \
627db96d56Sopenharmony_ci    } \
637db96d56Sopenharmony_ci    n = (size ? (sizeof(TYPE *) * (size - 1)) : 0); \
647db96d56Sopenharmony_ci    /* check if size can be added safely */ \
657db96d56Sopenharmony_ci    if (n > SIZE_MAX - sizeof(asdl_ ## NAME ## _seq)) { \
667db96d56Sopenharmony_ci        PyErr_NoMemory(); \
677db96d56Sopenharmony_ci        return NULL; \
687db96d56Sopenharmony_ci    } \
697db96d56Sopenharmony_ci    n += sizeof(asdl_ ## NAME ## _seq); \
707db96d56Sopenharmony_ci    seq = (asdl_ ## NAME ## _seq *)_PyArena_Malloc(arena, n); \
717db96d56Sopenharmony_ci    if (!seq) { \
727db96d56Sopenharmony_ci        PyErr_NoMemory(); \
737db96d56Sopenharmony_ci        return NULL; \
747db96d56Sopenharmony_ci    } \
757db96d56Sopenharmony_ci    memset(seq, 0, n); \
767db96d56Sopenharmony_ci    seq->size = size; \
777db96d56Sopenharmony_ci    seq->elements = (void**)seq->typed_elements; \
787db96d56Sopenharmony_ci    return seq; \
797db96d56Sopenharmony_ci}
807db96d56Sopenharmony_ci
817db96d56Sopenharmony_ci#define asdl_seq_GET_UNTYPED(S, I) _Py_RVALUE((S)->elements[(I)])
827db96d56Sopenharmony_ci#define asdl_seq_GET(S, I) _Py_RVALUE((S)->typed_elements[(I)])
837db96d56Sopenharmony_ci#define asdl_seq_LEN(S) _Py_RVALUE(((S) == NULL ? 0 : (S)->size))
847db96d56Sopenharmony_ci
857db96d56Sopenharmony_ci#ifdef Py_DEBUG
867db96d56Sopenharmony_ci#  define asdl_seq_SET(S, I, V) \
877db96d56Sopenharmony_ci    do { \
887db96d56Sopenharmony_ci        Py_ssize_t _asdl_i = (I); \
897db96d56Sopenharmony_ci        assert((S) != NULL); \
907db96d56Sopenharmony_ci        assert(0 <= _asdl_i && _asdl_i < (S)->size); \
917db96d56Sopenharmony_ci        (S)->typed_elements[_asdl_i] = (V); \
927db96d56Sopenharmony_ci    } while (0)
937db96d56Sopenharmony_ci#else
947db96d56Sopenharmony_ci#  define asdl_seq_SET(S, I, V) _Py_RVALUE((S)->typed_elements[I] = (V))
957db96d56Sopenharmony_ci#endif
967db96d56Sopenharmony_ci
977db96d56Sopenharmony_ci#ifdef Py_DEBUG
987db96d56Sopenharmony_ci#  define asdl_seq_SET_UNTYPED(S, I, V) \
997db96d56Sopenharmony_ci    do { \
1007db96d56Sopenharmony_ci        Py_ssize_t _asdl_i = (I); \
1017db96d56Sopenharmony_ci        assert((S) != NULL); \
1027db96d56Sopenharmony_ci        assert(0 <= _asdl_i && _asdl_i < (S)->size); \
1037db96d56Sopenharmony_ci        (S)->elements[_asdl_i] = (V); \
1047db96d56Sopenharmony_ci    } while (0)
1057db96d56Sopenharmony_ci#else
1067db96d56Sopenharmony_ci#  define asdl_seq_SET_UNTYPED(S, I, V) _Py_RVALUE((S)->elements[I] = (V))
1077db96d56Sopenharmony_ci#endif
1087db96d56Sopenharmony_ci
1097db96d56Sopenharmony_ci#ifdef __cplusplus
1107db96d56Sopenharmony_ci}
1117db96d56Sopenharmony_ci#endif
1127db96d56Sopenharmony_ci#endif /* !Py_INTERNAL_ASDL_H */
113