mirror of
https://github.com/YosysHQ/yosys
synced 2025-10-09 01:11:58 +00:00
pyosys: rewrite using pybind11
- Rewrite all Python features to use the pybind11 library instead of boost::python. Unlike boost::python, pybind11 is a header-only library that is just included by Pyosys code, saving a lot of compile time on wheels. - Factor out as much "translation" code from the generator into proper C++ files - Fix running the embedded interpreter not supporting "from pyosys import libyosys as ys" like wheels - Move Python-related elements to `pyosys` directory at the root of the repo - Slight shift in bridging semantics: - Containers are declared as "opaque types" and are passed by reference to Python - many methods have been implemented to make them feel right at home without the overhead/ambiguity of copying to Python and then copying back after mutation - Monitor/Pass use "trampoline" pattern to support virual methods overridable in Python: virtual methods no longer require `py_` prefix - Create really short test set for pyosys that just exercises basic functionality
This commit is contained in:
parent
f7120e9c2a
commit
88be728353
27 changed files with 2879 additions and 2674 deletions
|
@ -92,8 +92,9 @@ int main(int argc, char **argv)
|
|||
yosys_banner();
|
||||
yosys_setup();
|
||||
#ifdef WITH_PYTHON
|
||||
PyRun_SimpleString(("sys.path.append(\""+proc_self_dirname()+"\")").c_str());
|
||||
PyRun_SimpleString(("sys.path.append(\""+proc_share_dirname()+"plugins\")").c_str());
|
||||
py::object sys = py::module_::import("sys");
|
||||
sys.attr("path").attr("append")(proc_self_dirname());
|
||||
sys.attr("path").attr("append")(proc_share_dirname());
|
||||
#endif
|
||||
|
||||
if (argc == 2)
|
||||
|
@ -516,8 +517,9 @@ int main(int argc, char **argv)
|
|||
|
||||
yosys_setup();
|
||||
#ifdef WITH_PYTHON
|
||||
PyRun_SimpleString(("sys.path.append(\""+proc_self_dirname()+"\")").c_str());
|
||||
PyRun_SimpleString(("sys.path.append(\""+proc_share_dirname()+"plugins\")").c_str());
|
||||
py::object sys = py::module_::import("sys");
|
||||
sys.attr("path").attr("append")(proc_self_dirname());
|
||||
sys.attr("path").attr("append")(proc_share_dirname());
|
||||
#endif
|
||||
log_error_atexit = yosys_atexit;
|
||||
|
||||
|
@ -567,21 +569,18 @@ int main(int argc, char **argv)
|
|||
#endif
|
||||
} else if (scriptfile_python) {
|
||||
#ifdef WITH_PYTHON
|
||||
PyObject *sys = PyImport_ImportModule("sys");
|
||||
py::list new_argv;
|
||||
int py_argc = special_args.size() + 1;
|
||||
PyObject *new_argv = PyList_New(py_argc);
|
||||
PyList_SetItem(new_argv, 0, PyUnicode_FromString(scriptfile.c_str()));
|
||||
new_argv.append(scriptfile);
|
||||
for (int i = 1; i < py_argc; ++i)
|
||||
PyList_SetItem(new_argv, i, PyUnicode_FromString(special_args[i - 1].c_str()));
|
||||
new_argv.append(special_args[i - 1]);
|
||||
|
||||
PyObject *old_argv = PyObject_GetAttrString(sys, "argv");
|
||||
PyObject_SetAttrString(sys, "argv", new_argv);
|
||||
Py_DECREF(old_argv);
|
||||
py::setattr(sys, "argv", new_argv);
|
||||
|
||||
PyObject *py_path = PyUnicode_FromString(scriptfile.c_str());
|
||||
PyObject_SetAttrString(sys, "_yosys_script_path", py_path);
|
||||
Py_DECREF(py_path);
|
||||
PyRun_SimpleString("import os, sys; sys.path.insert(0, os.path.dirname(os.path.abspath(sys._yosys_script_path)))");
|
||||
py::object Path = py::module_::import("pathlib").attr("Path");
|
||||
py::object scriptfile_python_path = Path(scriptfile).attr("parent");
|
||||
|
||||
sys.attr("path").attr("insert")(0, py::str(scriptfile_python_path));
|
||||
|
||||
FILE *scriptfp = fopen(scriptfile.c_str(), "r");
|
||||
if (scriptfp == nullptr) {
|
||||
|
|
|
@ -64,13 +64,8 @@
|
|||
#endif
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
# define INIT_MODULE PyInit_libyosys
|
||||
extern "C" PyObject* INIT_MODULE();
|
||||
#else
|
||||
# define INIT_MODULE initlibyosys
|
||||
extern "C" void INIT_MODULE();
|
||||
#endif
|
||||
extern "C" PyObject* PyInit_libyosys();
|
||||
extern "C" PyObject* PyInit_pyosys();
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
|
@ -189,6 +184,17 @@ int run_command(const std::string &command, std::function<void(const std::string
|
|||
bool already_setup = false;
|
||||
bool already_shutdown = false;
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
// Include pyosys as a module so 'from pyosys import libyosys' also works
|
||||
// in interpreter mode.
|
||||
//
|
||||
// This should not affect using wheels as the dylib has to actually be called
|
||||
// pyosys.so for this module to be interacted with at all.
|
||||
PYBIND11_MODULE(pyosys, m) {
|
||||
m.add_object("libyosys", m.import("libyosys"));
|
||||
}
|
||||
#endif
|
||||
|
||||
void yosys_setup()
|
||||
{
|
||||
if(already_setup)
|
||||
|
@ -199,11 +205,12 @@ void yosys_setup()
|
|||
IdString::ensure_prepopulated();
|
||||
|
||||
#ifdef WITH_PYTHON
|
||||
// With Python 3.12, calling PyImport_AppendInittab on an already
|
||||
// Starting Python 3.12, calling PyImport_AppendInittab on an already
|
||||
// initialized platform fails (such as when libyosys is imported
|
||||
// from a Python interpreter)
|
||||
if (!Py_IsInitialized()) {
|
||||
PyImport_AppendInittab((char*)"libyosys", INIT_MODULE);
|
||||
PyImport_AppendInittab((char*)"libyosys", PyInit_libyosys);
|
||||
PyImport_AppendInittab((char*)"pyosys", PyInit_pyosys);
|
||||
Py_Initialize();
|
||||
PyRun_SimpleString("import sys");
|
||||
signal(SIGINT, SIG_DFL);
|
||||
|
|
|
@ -55,6 +55,9 @@
|
|||
|
||||
#ifdef WITH_PYTHON
|
||||
#include <Python.h>
|
||||
#include <pybind11/pybind11.h>
|
||||
|
||||
namespace py = pybind11;
|
||||
#endif
|
||||
|
||||
#ifndef _YOSYS_
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue