/*
- * Copyright (c) 2012 ARM Limited
+ * Copyright (c) 2012, 2017 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
#include <Python.h>
+#include "sim/init.hh"
+
#include <marshal.h>
#include <zlib.h>
#include "base/misc.hh"
#include "base/types.hh"
#include "config/have_protobuf.hh"
+#include "python/pybind11/pybind.hh"
#include "sim/async.hh"
#include "sim/core.hh"
-#include "sim/init.hh"
#if HAVE_PROTOBUF
#include <google/protobuf/stubs/common.h>
+
#endif
using namespace std;
+namespace py = pybind11;
// The python library is totally messed up with respect to constness,
// so make a simple macro to make life a little easier
}
/*
- * Load and initialize all of the python parts of M5, including Swig
- * and the embedded module importer.
+ * Load and initialize all of the python parts of M5.
*/
int
EmbeddedPython::initAll()
return 0;
}
-EmbeddedSwig::EmbeddedSwig(void (*init_func)())
- : initFunc(init_func)
+EmbeddedPyBind::EmbeddedPyBind(const char *_name,
+ void (*init_func)(py::module &),
+ const char *_base)
+ : initFunc(init_func), registered(false), name(_name), base(_base)
{
- getList().push_back(this);
+ getMap()[_name] = this;
}
-list<EmbeddedSwig *> &
-EmbeddedSwig::getList()
+EmbeddedPyBind::EmbeddedPyBind(const char *_name,
+ void (*init_func)(py::module &))
+ : initFunc(init_func), registered(false), name(_name), base("")
{
- static list<EmbeddedSwig *> the_list;
- return the_list;
+ getMap()[_name] = this;
}
void
-EmbeddedSwig::initAll()
+EmbeddedPyBind::init(py::module &m)
{
- // initialize SWIG modules. initSwig() is autogenerated and calls
- // all of the individual swig initialization functions.
- list<EmbeddedSwig *>::iterator i = getList().begin();
- list<EmbeddedSwig *>::iterator end = getList().end();
- for (; i != end; ++i)
- (*i)->initFunc();
+ if (!registered) {
+ initFunc(m);
+ registered = true;
+ } else {
+ cprintf("Warning: %s already registered.\n", name);
+ }
+}
+
+bool
+EmbeddedPyBind::depsReady() const
+{
+ return base.empty() || getMap()[base]->registered;
+}
+
+std::map<std::string, EmbeddedPyBind *> &
+EmbeddedPyBind::getMap()
+{
+ static std::map<std::string, EmbeddedPyBind *> objs;
+ return objs;
+}
+
+void
+EmbeddedPyBind::initAll()
+{
+ std::list<EmbeddedPyBind *> pending;
+
+ py::module m_m5 = py::module("_m5");
+ m_m5.attr("__package__") = py::cast("_m5");
+
+ pybind_init_core(m_m5);
+ pybind_init_debug(m_m5);
+
+ pybind_init_event(m_m5);
+ pybind_init_pyobject(m_m5);
+ pybind_init_stats(m_m5);
+
+ for (auto &kv : getMap()) {
+ auto &obj = kv.second;
+ if (obj->base.empty()) {
+ obj->init(m_m5);
+ } else {
+ pending.push_back(obj);
+ }
+ }
+
+ while (!pending.empty()) {
+ for (auto it = pending.begin(); it != pending.end(); ) {
+ EmbeddedPyBind &obj = **it;
+ if (obj.depsReady()) {
+ obj.init(m_m5);
+ it = pending.erase(it);
+ } else {
+ ++it;
+ }
+ }
+ }
}
int
initM5Python()
{
- EmbeddedSwig::initAll();
+ EmbeddedPyBind::initAll();
return EmbeddedPython::initAll();
}