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