mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 05:31:20 +00:00 
			
		
		
		
	 4ce2a202c7
			
		
	
	
		4ce2a202c7
		
			
		
	
	
	
	
		
			
			Replace Py_INCREF() with Py_NewRef() in C files of the Parser/ directory and in the PEG generator.
		
			
				
	
	
		
			172 lines
		
	
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			172 lines
		
	
	
	
		
			4.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include "pegen.h"
 | |
| #include "pycore_compile.h"       // _PyAST_Compile()
 | |
| 
 | |
| 
 | |
| PyObject *
 | |
| _build_return_object(mod_ty module, int mode, PyObject *filename_ob, PyArena *arena)
 | |
| {
 | |
|     PyObject *result = NULL;
 | |
| 
 | |
|     if (mode == 2) {
 | |
|         result = (PyObject *)_PyAST_Compile(module, filename_ob, NULL, -1, arena);
 | |
|     } else if (mode == 1) {
 | |
|         result = PyAST_mod2obj(module);
 | |
|     } else {
 | |
|         result = Py_NewRef(Py_None);
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| parse_file(PyObject *self, PyObject *args, PyObject *kwds)
 | |
| {
 | |
|     static char *keywords[] = {"file", "mode", NULL};
 | |
|     const char *filename;
 | |
|     int mode = 2;
 | |
|     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i", keywords, &filename, &mode)) {
 | |
|         return NULL;
 | |
|     }
 | |
|     if (mode < 0 || mode > 2) {
 | |
|         return PyErr_Format(PyExc_ValueError, "Bad mode, must be 0 <= mode <= 2");
 | |
|     }
 | |
| 
 | |
|     PyArena *arena = _PyArena_New();
 | |
|     if (arena == NULL) {
 | |
|         return NULL;
 | |
|     }
 | |
| 
 | |
|     PyObject *result = NULL;
 | |
| 
 | |
|     PyObject *filename_ob = PyUnicode_FromString(filename);
 | |
|     if (filename_ob == NULL) {
 | |
|         goto error;
 | |
|     }
 | |
| 
 | |
|     FILE *fp = fopen(filename, "rb");
 | |
|     if (fp == NULL) {
 | |
|         PyErr_SetFromErrnoWithFilename(PyExc_OSError, filename);
 | |
|         goto error;
 | |
|     }
 | |
| 
 | |
|     PyCompilerFlags flags = _PyCompilerFlags_INIT;
 | |
|     mod_ty res = _PyPegen_run_parser_from_file_pointer(
 | |
|                         fp, Py_file_input, filename_ob,
 | |
|                         NULL, NULL, NULL, &flags, NULL, arena);
 | |
|     fclose(fp);
 | |
|     if (res == NULL) {
 | |
|         goto error;
 | |
|     }
 | |
| 
 | |
|     result = _build_return_object(res, mode, filename_ob, arena);
 | |
| 
 | |
| error:
 | |
|     Py_XDECREF(filename_ob);
 | |
|     _PyArena_Free(arena);
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| parse_string(PyObject *self, PyObject *args, PyObject *kwds)
 | |
| {
 | |
|     static char *keywords[] = {"str", "mode", NULL};
 | |
|     const char *the_string;
 | |
|     int mode = 2;
 | |
|     if (!PyArg_ParseTupleAndKeywords(args, kwds, "s|i", keywords, &the_string, &mode)) {
 | |
|         return NULL;
 | |
|     }
 | |
|     if (mode < 0 || mode > 2) {
 | |
|         return PyErr_Format(PyExc_ValueError, "Bad mode, must be 0 <= mode <= 2");
 | |
|     }
 | |
| 
 | |
|     PyArena *arena = _PyArena_New();
 | |
|     if (arena == NULL) {
 | |
|         return NULL;
 | |
|     }
 | |
| 
 | |
|     PyObject *result = NULL;
 | |
| 
 | |
|     PyObject *filename_ob = PyUnicode_FromString("<string>");
 | |
|     if (filename_ob == NULL) {
 | |
|         goto error;
 | |
|     }
 | |
| 
 | |
|     PyCompilerFlags flags = _PyCompilerFlags_INIT;
 | |
|     mod_ty res = _PyPegen_run_parser_from_string(the_string, Py_file_input, filename_ob,
 | |
|                                         &flags, arena);
 | |
|     if (res == NULL) {
 | |
|         goto error;
 | |
|     }
 | |
|     result = _build_return_object(res, mode, filename_ob, arena);
 | |
| 
 | |
| error:
 | |
|     Py_XDECREF(filename_ob);
 | |
|     _PyArena_Free(arena);
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| clear_memo_stats(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored))
 | |
| {
 | |
| #if defined(PY_DEBUG)
 | |
|     _PyPegen_clear_memo_statistics();
 | |
| #endif
 | |
|     Py_RETURN_NONE;
 | |
| }
 | |
| 
 | |
| static PyObject *
 | |
| get_memo_stats(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored))
 | |
| {
 | |
| #if defined(PY_DEBUG)
 | |
|     return _PyPegen_get_memo_statistics();
 | |
| #else
 | |
|     Py_RETURN_NONE;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| // TODO: Write to Python's sys.stdout instead of C's stdout.
 | |
| static PyObject *
 | |
| dump_memo_stats(PyObject *Py_UNUSED(self), PyObject *Py_UNUSED(ignored))
 | |
| {
 | |
| #if defined(PY_DEBUG)
 | |
|     PyObject *list = _PyPegen_get_memo_statistics();
 | |
|     if (list == NULL) {
 | |
|         return NULL;
 | |
|     }
 | |
|     Py_ssize_t len = PyList_Size(list);
 | |
|     for (Py_ssize_t i = 0; i < len; i++) {
 | |
|         PyObject *value = PyList_GetItem(list, i);  // Borrowed reference.
 | |
|         long count = PyLong_AsLong(value);
 | |
|         if (count < 0) {
 | |
|             break;
 | |
|         }
 | |
|         if (count > 0) {
 | |
|             printf("%4zd %9ld\n", i, count);
 | |
|         }
 | |
|     }
 | |
|     Py_DECREF(list);
 | |
| #endif
 | |
|     Py_RETURN_NONE;
 | |
| }
 | |
| 
 | |
| static PyMethodDef ParseMethods[] = {
 | |
|     {"parse_file", _PyCFunction_CAST(parse_file), METH_VARARGS|METH_KEYWORDS, "Parse a file."},
 | |
|     {"parse_string", _PyCFunction_CAST(parse_string), METH_VARARGS|METH_KEYWORDS, "Parse a string."},
 | |
|     {"clear_memo_stats", clear_memo_stats, METH_NOARGS},
 | |
|     {"dump_memo_stats", dump_memo_stats, METH_NOARGS},
 | |
|     {"get_memo_stats", get_memo_stats, METH_NOARGS},
 | |
|     {NULL, NULL, 0, NULL}        /* Sentinel */
 | |
| };
 | |
| 
 | |
| static struct PyModuleDef parsemodule = {
 | |
|     PyModuleDef_HEAD_INIT,
 | |
|     .m_name = "parse",
 | |
|     .m_doc = "A parser.",
 | |
|     .m_methods = ParseMethods,
 | |
| };
 | |
| 
 | |
| PyMODINIT_FUNC
 | |
| PyInit_parse(void)
 | |
| {
 | |
|     return PyModule_Create(&parsemodule);
 | |
| }
 |