1 #ifndef Py_INTERNAL_ASDL_H
2 #define Py_INTERNAL_ASDL_H
3 #ifdef __cplusplus
4 extern "C" {
5 #endif
6 
7 #ifndef Py_BUILD_CORE
8 #  error "this header requires Py_BUILD_CORE define"
9 #endif
10 
11 #include "pycore_pyarena.h"       // _PyArena_Malloc()
12 
13 typedef PyObject * identifier;
14 typedef PyObject * string;
15 typedef PyObject * object;
16 typedef PyObject * constant;
17 
18 /* It would be nice if the code generated by asdl_c.py was completely
19    independent of Python, but it is a goal the requires too much work
20    at this stage.  So, for example, I'll represent identifiers as
21    interned Python strings.
22 */
23 
24 #define _ASDL_SEQ_HEAD \
25     Py_ssize_t size;   \
26     void **elements;
27 
28 typedef struct {
29     _ASDL_SEQ_HEAD
30 } asdl_seq;
31 
32 typedef struct {
33     _ASDL_SEQ_HEAD
34     void *typed_elements[1];
35 } asdl_generic_seq;
36 
37 typedef struct {
38     _ASDL_SEQ_HEAD
39     PyObject *typed_elements[1];
40 } asdl_identifier_seq;
41 
42 typedef struct {
43     _ASDL_SEQ_HEAD
44     int typed_elements[1];
45 } asdl_int_seq;
46 
47 asdl_generic_seq *_Py_asdl_generic_seq_new(Py_ssize_t size, PyArena *arena);
48 asdl_identifier_seq *_Py_asdl_identifier_seq_new(Py_ssize_t size, PyArena *arena);
49 asdl_int_seq *_Py_asdl_int_seq_new(Py_ssize_t size, PyArena *arena);
50 
51 
52 #define GENERATE_ASDL_SEQ_CONSTRUCTOR(NAME, TYPE) \
53 asdl_ ## NAME ## _seq *_Py_asdl_ ## NAME ## _seq_new(Py_ssize_t size, PyArena *arena) \
54 { \
55     asdl_ ## NAME ## _seq *seq = NULL; \
56     size_t n; \
57     /* check size is sane */ \
58     if (size < 0 || \
59         (size && (((size_t)size - 1) > (SIZE_MAX / sizeof(void *))))) { \
60         PyErr_NoMemory(); \
61         return NULL; \
62     } \
63     n = (size ? (sizeof(TYPE *) * (size - 1)) : 0); \
64     /* check if size can be added safely */ \
65     if (n > SIZE_MAX - sizeof(asdl_ ## NAME ## _seq)) { \
66         PyErr_NoMemory(); \
67         return NULL; \
68     } \
69     n += sizeof(asdl_ ## NAME ## _seq); \
70     seq = (asdl_ ## NAME ## _seq *)_PyArena_Malloc(arena, n); \
71     if (!seq) { \
72         PyErr_NoMemory(); \
73         return NULL; \
74     } \
75     memset(seq, 0, n); \
76     seq->size = size; \
77     seq->elements = (void**)seq->typed_elements; \
78     return seq; \
79 }
80 
81 #define asdl_seq_GET_UNTYPED(S, I) (S)->elements[(I)]
82 #define asdl_seq_GET(S, I) (S)->typed_elements[(I)]
83 #define asdl_seq_LEN(S) ((S) == NULL ? 0 : (S)->size)
84 
85 #ifdef Py_DEBUG
86 #  define asdl_seq_SET(S, I, V) \
87     do { \
88         Py_ssize_t _asdl_i = (I); \
89         assert((S) != NULL); \
90         assert(0 <= _asdl_i && _asdl_i < (S)->size); \
91         (S)->typed_elements[_asdl_i] = (V); \
92     } while (0)
93 #else
94 #  define asdl_seq_SET(S, I, V) (S)->typed_elements[I] = (V)
95 #endif
96 
97 #ifdef Py_DEBUG
98 #  define asdl_seq_SET_UNTYPED(S, I, V) \
99     do { \
100         Py_ssize_t _asdl_i = (I); \
101         assert((S) != NULL); \
102         assert(0 <= _asdl_i && _asdl_i < (S)->size); \
103         (S)->elements[_asdl_i] = (V); \
104     } while (0)
105 #else
106 #  define asdl_seq_SET_UNTYPED(S, I, V) (S)->elements[I] = (V)
107 #endif
108 
109 #ifdef __cplusplus
110 }
111 #endif
112 #endif /* !Py_INTERNAL_ASDL_H */
113