From e6ee56c6571999631ce31b05d0e563d66a7bbdd8 Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 9 Sep 2010 14:15:42 -0700 Subject: init: don't build files that centralize python and swig code Instead of putting all object files into m5/object/__init__.py, interrogate the importer to find out what should be imported. Instead of creating a single file that lists all of the embedded python modules, use static object construction to put those objects onto a list. Do something similar for embedded swig (C++) code. --- src/sim/init.cc | 121 ++++++++++++++++++++++++++++++++++++++++---------------- src/sim/init.hh | 34 +++++++++++++--- 2 files changed, 116 insertions(+), 39 deletions(-) (limited to 'src/sim') diff --git a/src/sim/init.cc b/src/sim/init.cc index 1ec09369d..bd835917e 100644 --- a/src/sim/init.cc +++ b/src/sim/init.cc @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -104,69 +105,121 @@ initSignals() signal(SIGABRT, abortHandler); } +// The python library is totally messed up with respect to constness, +// so make a simple macro to make life a little easier +#define PyCC(x) (const_cast(x)) + +EmbeddedPython *EmbeddedPython::importer = NULL; +PyObject *EmbeddedPython::importerModule = NULL; +EmbeddedPython::EmbeddedPython(const char *filename, const char *abspath, + const char *modpath, const char *code, int zlen, int len) + : filename(filename), abspath(abspath), modpath(modpath), code(code), + zlen(zlen), len(len) +{ + // if we've added the importer keep track of it because we need it + // to bootstrap. + if (string(modpath) == string("importer")) + importer = this; + else + getList().push_back(this); +} + +list & +EmbeddedPython::getList() +{ + static list the_list; + return the_list; +} + /* * Uncompress and unmarshal the code object stored in the - * EmbeddedPyModule + * EmbeddedPython */ PyObject * -getCode(const EmbeddedPyModule *pymod) +EmbeddedPython::getCode() const { - assert(pymod->zlen == pymod->code_end - pymod->code); - Bytef *marshalled = new Bytef[pymod->mlen]; - uLongf unzlen = pymod->mlen; - int ret = uncompress(marshalled, &unzlen, (const Bytef *)pymod->code, - pymod->zlen); + Bytef marshalled[len]; + uLongf unzlen = len; + int ret = uncompress(marshalled, &unzlen, (const Bytef *)code, zlen); if (ret != Z_OK) panic("Could not uncompress code: %s\n", zError(ret)); - assert(unzlen == (uLongf)pymod->mlen); + assert(unzlen == (uLongf)len); - return PyMarshal_ReadObjectFromString((char *)marshalled, pymod->mlen); + return PyMarshal_ReadObjectFromString((char *)marshalled, len); } -// The python library is totally messed up with respect to constness, -// so make a simple macro to make life a little easier -#define PyCC(x) (const_cast(x)) +bool +EmbeddedPython::addModule() const +{ + PyObject *code = getCode(); + PyObject *result = PyObject_CallMethod(importerModule, PyCC("add_module"), + PyCC("sssO"), filename, abspath, modpath, code); + if (!result) { + PyErr_Print(); + return false; + } + + Py_DECREF(result); + return true; +} /* * Load and initialize all of the python parts of M5, including Swig * and the embedded module importer. */ int -initM5Python() +EmbeddedPython::initAll() { - extern void initSwig(); - - // initialize SWIG modules. initSwig() is autogenerated and calls - // all of the individual swig initialization functions. - initSwig(); - // Load the importer module - PyObject *code = getCode(&embeddedPyImporter); - PyObject *module = PyImport_ExecCodeModule(PyCC("importer"), code); - if (!module) { + PyObject *code = importer->getCode(); + importerModule = PyImport_ExecCodeModule(PyCC("importer"), code); + if (!importerModule) { PyErr_Print(); return 1; } // Load the rest of the embedded python files into the embedded // python importer - const EmbeddedPyModule *pymod = &embeddedPyModules[0]; - while (pymod->filename) { - PyObject *code = getCode(pymod); - PyObject *result = PyObject_CallMethod(module, PyCC("add_module"), - PyCC("sssO"), pymod->filename, pymod->abspath, pymod->modpath, - code); - if (!result) { - PyErr_Print(); + list::iterator i = getList().begin(); + list::iterator end = getList().end(); + for (; i != end; ++i) + if (!(*i)->addModule()) return 1; - } - Py_DECREF(result); - ++pymod; - } return 0; } +EmbeddedSwig::EmbeddedSwig(void (*init_func)()) + : initFunc(init_func) +{ + getList().push_back(this); +} + +list & +EmbeddedSwig::getList() +{ + static list the_list; + return the_list; +} + +void +EmbeddedSwig::initAll() +{ + // initialize SWIG modules. initSwig() is autogenerated and calls + // all of the individual swig initialization functions. + list::iterator i = getList().begin(); + list::iterator end = getList().end(); + for (; i != end; ++i) + (*i)->initFunc(); +} + +int +initM5Python() +{ + EmbeddedSwig::initAll(); + return EmbeddedPython::initAll(); +} + /* * Start up the M5 simulator. This mostly vectors into the python * main function. diff --git a/src/sim/init.hh b/src/sim/init.hh index 76cdcb74e..8fc0be982 100644 --- a/src/sim/init.hh +++ b/src/sim/init.hh @@ -34,19 +34,43 @@ /* * Data structure describing an embedded python file. */ -struct EmbeddedPyModule +#include + +#ifndef PyObject_HEAD +struct _object; +typedef _object PyObject; +#endif + +struct EmbeddedPython { const char *filename; const char *abspath; const char *modpath; const char *code; - const char *code_end; int zlen; - int mlen; + int len; + + EmbeddedPython(const char *filename, const char *abspath, + const char *modpath, const char *code, int zlen, int len); + + PyObject *getCode() const; + bool addModule() const; + + static EmbeddedPython *importer; + static PyObject *importerModule; + static std::list &getList(); + static int initAll(); }; -extern const EmbeddedPyModule embeddedPyImporter; -extern const EmbeddedPyModule embeddedPyModules[]; +struct EmbeddedSwig +{ + void (*initFunc)(); + + EmbeddedSwig(void (*init_func)()); + + static std::list &getList(); + static void initAll(); +}; void initSignals(); int initM5Python(); -- cgit v1.2.3