sim, arch, base: Refactor the base remote GDB class.
[gem5.git] / src / sim / init.cc
index 2e1dd629ca0cc0f68ea7bf58c525932f0f3a13fb..50612895b360cffcb0007bbc35b76dda0c612f0b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * 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
@@ -43,6 +43,8 @@
 
 #include <Python.h>
 
+#include "sim/init.hh"
+
 #include <marshal.h>
 #include <zlib.h>
 
 #include <string>
 
 #include "base/cprintf.hh"
-#include "base/misc.hh"
+#include "base/logging.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
@@ -123,8 +127,7 @@ EmbeddedPython::addModule() const
 }
 
 /*
- * 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()
@@ -148,44 +151,86 @@ EmbeddedPython::initAll()
     return 0;
 }
 
-EmbeddedSwig::EmbeddedSwig(void (*init_func)(), const string& _context)
-    : initFunc(init_func), context(_context)
+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)
+{
+    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()
 {
-    char* old_context = _Py_PackageContext;
-    // initialize SWIG modules. initFunc() is autogenerated and calls
-    // all of the individual swig initialization functions.
-    for (auto i : getList()) {
-        // to ensure that the loaded modules are placed in the right
-        // package we have to be a bit unorthodox and directly
-        // manipulate the package context since swig simply calls
-        // Py_InitModule with nothing but the module name of the
-        // wrapper
-        char* cstr = new char[i->context.size() + 1];
-        strcpy(cstr, i->context.c_str());
-        _Py_PackageContext = cstr;
-        i->initFunc();
-        delete[] cstr;
+    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;
+            }
+        }
     }
-    _Py_PackageContext = old_context;
 }
 
 int
 initM5Python()
 {
-    EmbeddedSwig::initAll();
+    EmbeddedPyBind::initAll();
     return EmbeddedPython::initAll();
 }