diff options
Diffstat (limited to 'src/sim/init.cc')
-rw-r--r-- | src/sim/init.cc | 121 |
1 files changed, 87 insertions, 34 deletions
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 <marshal.h> #include <signal.h> +#include <list> #include <iostream> #include <string> #include <zlib.h> @@ -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<char *>(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 *> & +EmbeddedPython::getList() +{ + static list<EmbeddedPython *> 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<char *>(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<EmbeddedPython *>::iterator i = getList().begin(); + list<EmbeddedPython *>::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 *> & +EmbeddedSwig::getList() +{ + static list<EmbeddedSwig *> the_list; + return the_list; +} + +void +EmbeddedSwig::initAll() +{ + // 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(); +} + +int +initM5Python() +{ + EmbeddedSwig::initAll(); + return EmbeddedPython::initAll(); +} + /* * Start up the M5 simulator. This mostly vectors into the python * main function. |