1 #include "Python.h"
2 
3 #include "code.h"
4 #include "Python-ast.h"
5 #include "symtable.h"
6 
7 #include "clinic/symtablemodule.c.h"
8 /*[clinic input]
9 module _symtable
10 [clinic start generated code]*/
11 /*[clinic end generated code: output=da39a3ee5e6b4b0d input=f4685845a7100605]*/
12 
13 
14 /*[clinic input]
15 _symtable.symtable
16 
17     source:    object
18     filename:  object(converter='PyUnicode_FSDecoder')
19     startstr:  str
20     /
21 
22 Return symbol and scope dictionaries used internally by compiler.
23 [clinic start generated code]*/
24 
25 static PyObject *
_symtable_symtable_impl(PyObject * module,PyObject * source,PyObject * filename,const char * startstr)26 _symtable_symtable_impl(PyObject *module, PyObject *source,
27                         PyObject *filename, const char *startstr)
28 /*[clinic end generated code: output=59eb0d5fc7285ac4 input=9dd8a50c0c36a4d7]*/
29 {
30     struct symtable *st;
31     PyObject *t;
32     int start;
33     PyCompilerFlags cf = _PyCompilerFlags_INIT;
34     PyObject *source_copy = NULL;
35 
36     cf.cf_flags = PyCF_SOURCE_IS_UTF8;
37 
38     const char *str = _Py_SourceAsString(source, "symtable", "string or bytes", &cf, &source_copy);
39     if (str == NULL) {
40         return NULL;
41     }
42 
43     if (strcmp(startstr, "exec") == 0)
44         start = Py_file_input;
45     else if (strcmp(startstr, "eval") == 0)
46         start = Py_eval_input;
47     else if (strcmp(startstr, "single") == 0)
48         start = Py_single_input;
49     else {
50         PyErr_SetString(PyExc_ValueError,
51            "symtable() arg 3 must be 'exec' or 'eval' or 'single'");
52         Py_DECREF(filename);
53         Py_XDECREF(source_copy);
54         return NULL;
55     }
56     st = _Py_SymtableStringObjectFlags(str, filename, start, &cf);
57     Py_DECREF(filename);
58     Py_XDECREF(source_copy);
59     if (st == NULL) {
60         return NULL;
61     }
62     t = (PyObject *)st->st_top;
63     Py_INCREF(t);
64     PyMem_Free((void *)st->st_future);
65     PySymtable_Free(st);
66     return t;
67 }
68 
69 static PyMethodDef symtable_methods[] = {
70     _SYMTABLE_SYMTABLE_METHODDEF
71     {NULL,              NULL}           /* sentinel */
72 };
73 
74 static struct PyModuleDef symtablemodule = {
75     PyModuleDef_HEAD_INIT,
76     "_symtable",
77     NULL,
78     -1,
79     symtable_methods,
80     NULL,
81     NULL,
82     NULL,
83     NULL
84 };
85 
86 PyMODINIT_FUNC
PyInit__symtable(void)87 PyInit__symtable(void)
88 {
89     PyObject *m;
90 
91     if (PyType_Ready(&PySTEntry_Type) < 0)
92         return NULL;
93 
94     m = PyModule_Create(&symtablemodule);
95     if (m == NULL)
96         return NULL;
97     PyModule_AddIntMacro(m, USE);
98     PyModule_AddIntMacro(m, DEF_GLOBAL);
99     PyModule_AddIntMacro(m, DEF_NONLOCAL);
100     PyModule_AddIntMacro(m, DEF_LOCAL);
101     PyModule_AddIntMacro(m, DEF_PARAM);
102     PyModule_AddIntMacro(m, DEF_FREE);
103     PyModule_AddIntMacro(m, DEF_FREE_CLASS);
104     PyModule_AddIntMacro(m, DEF_IMPORT);
105     PyModule_AddIntMacro(m, DEF_BOUND);
106     PyModule_AddIntMacro(m, DEF_ANNOT);
107 
108     PyModule_AddIntConstant(m, "TYPE_FUNCTION", FunctionBlock);
109     PyModule_AddIntConstant(m, "TYPE_CLASS", ClassBlock);
110     PyModule_AddIntConstant(m, "TYPE_MODULE", ModuleBlock);
111 
112     PyModule_AddIntMacro(m, LOCAL);
113     PyModule_AddIntMacro(m, GLOBAL_EXPLICIT);
114     PyModule_AddIntMacro(m, GLOBAL_IMPLICIT);
115     PyModule_AddIntMacro(m, FREE);
116     PyModule_AddIntMacro(m, CELL);
117 
118     PyModule_AddIntConstant(m, "SCOPE_OFF", SCOPE_OFFSET);
119     PyModule_AddIntMacro(m, SCOPE_MASK);
120 
121     if (PyErr_Occurred()) {
122         Py_DECREF(m);
123         m = 0;
124     }
125     return m;
126 }
127