gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
init.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, 2017 ARM Limited
3  * All rights reserved
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Copyright (c) 2000-2005 The Regents of The University of Michigan
15  * Copyright (c) 2008 The Hewlett-Packard Development Company
16  * All rights reserved.
17  *
18  * Redistribution and use in source and binary forms, with or without
19  * modification, are permitted provided that the following conditions are
20  * met: redistributions of source code must retain the above copyright
21  * notice, this list of conditions and the following disclaimer;
22  * redistributions in binary form must reproduce the above copyright
23  * notice, this list of conditions and the following disclaimer in the
24  * documentation and/or other materials provided with the distribution;
25  * neither the name of the copyright holders nor the names of its
26  * contributors may be used to endorse or promote products derived from
27  * this software without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  *
41  * Authors: Nathan Binkert
42  */
43 
44 #include <Python.h>
45 
46 #include "sim/init.hh"
47 
48 #include <marshal.h>
49 #include <zlib.h>
50 
51 #include <iostream>
52 #include <list>
53 #include <string>
54 
55 #include "base/cprintf.hh"
56 #include "base/misc.hh"
57 #include "base/types.hh"
58 #include "config/have_protobuf.hh"
60 #include "sim/async.hh"
61 #include "sim/core.hh"
62 
63 #if HAVE_PROTOBUF
64 #include <google/protobuf/stubs/common.h>
65 
66 #endif
67 
68 using namespace std;
69 namespace py = pybind11;
70 
71 // The python library is totally messed up with respect to constness,
72 // so make a simple macro to make life a little easier
73 #define PyCC(x) (const_cast<char *>(x))
74 
77 EmbeddedPython::EmbeddedPython(const char *filename, const char *abspath,
78  const char *modpath, const unsigned char *code, int zlen, int len)
79  : filename(filename), abspath(abspath), modpath(modpath), code(code),
80  zlen(zlen), len(len)
81 {
82  // if we've added the importer keep track of it because we need it
83  // to bootstrap.
84  if (string(modpath) == string("importer"))
85  importer = this;
86  else
87  getList().push_back(this);
88 }
89 
92 {
93  static list<EmbeddedPython *> the_list;
94  return the_list;
95 }
96 
97 /*
98  * Uncompress and unmarshal the code object stored in the
99  * EmbeddedPython
100  */
101 PyObject *
103 {
104  Bytef marshalled[len];
105  uLongf unzlen = len;
106  int ret = uncompress(marshalled, &unzlen, (const Bytef *)code, zlen);
107  if (ret != Z_OK)
108  panic("Could not uncompress code: %s\n", zError(ret));
109  assert(unzlen == (uLongf)len);
110 
111  return PyMarshal_ReadObjectFromString((char *)marshalled, len);
112 }
113 
114 bool
116 {
117  PyObject *code = getCode();
118  PyObject *result = PyObject_CallMethod(importerModule, PyCC("add_module"),
119  PyCC("sssO"), filename, abspath, modpath, code);
120  if (!result) {
121  PyErr_Print();
122  return false;
123  }
124 
125  Py_DECREF(result);
126  return true;
127 }
128 
129 /*
130  * Load and initialize all of the python parts of M5.
131  */
132 int
134 {
135  // Load the importer module
137  importerModule = PyImport_ExecCodeModule(PyCC("importer"), code);
138  if (!importerModule) {
139  PyErr_Print();
140  return 1;
141  }
142 
143  // Load the rest of the embedded python files into the embedded
144  // python importer
147  for (; i != end; ++i)
148  if (!(*i)->addModule())
149  return 1;
150 
151  return 0;
152 }
153 
154 EmbeddedPyBind::EmbeddedPyBind(const char *_name,
155  void (*init_func)(py::module &),
156  const char *_base)
157  : initFunc(init_func), registered(false), name(_name), base(_base)
158 {
159  getMap()[_name] = this;
160 }
161 
162 EmbeddedPyBind::EmbeddedPyBind(const char *_name,
163  void (*init_func)(py::module &))
164  : initFunc(init_func), registered(false), name(_name), base("")
165 {
166  getMap()[_name] = this;
167 }
168 
169 void
171 {
172  if (!registered) {
173  initFunc(m);
174  registered = true;
175  } else {
176  cprintf("Warning: %s already registered.\n", name);
177  }
178 }
179 
180 bool
182 {
183  return base.empty() || getMap()[base]->registered;
184 }
185 
186 std::map<std::string, EmbeddedPyBind *> &
188 {
189  static std::map<std::string, EmbeddedPyBind *> objs;
190  return objs;
191 }
192 
193 void
195 {
197 
198  py::module m_m5 = py::module("_m5");
199  m_m5.attr("__package__") = py::cast("_m5");
200 
201  pybind_init_core(m_m5);
202  pybind_init_debug(m_m5);
203 
204  pybind_init_event(m_m5);
205  pybind_init_pyobject(m_m5);
206  pybind_init_stats(m_m5);
207 
208  for (auto &kv : getMap()) {
209  auto &obj = kv.second;
210  if (obj->base.empty()) {
211  obj->init(m_m5);
212  } else {
213  pending.push_back(obj);
214  }
215  }
216 
217  while (!pending.empty()) {
218  for (auto it = pending.begin(); it != pending.end(); ) {
219  EmbeddedPyBind &obj = **it;
220  if (obj.depsReady()) {
221  obj.init(m_m5);
222  it = pending.erase(it);
223  } else {
224  ++it;
225  }
226  }
227  }
228 }
229 
230 int
232 {
234  return EmbeddedPython::initAll();
235 }
236 
237 /*
238  * Make the commands array weak so that they can be overridden (used
239  * by unit tests to specify a different python main function.
240  */
241 const char * __attribute__((weak)) m5MainCommands[] = {
242  "import m5",
243  "m5.main()",
244  0 // sentinel is required
245 };
246 
247 /*
248  * Start up the M5 simulator. This mostly vectors into the python
249  * main function.
250  */
251 int
252 m5Main(int argc, char **argv)
253 {
254 #if HAVE_PROTOBUF
255  // Verify that the version of the protobuf library that we linked
256  // against is compatible with the version of the headers we
257  // compiled against.
258  GOOGLE_PROTOBUF_VERIFY_VERSION;
259 #endif
260 
261  PySys_SetArgv(argc, argv);
262 
263  // We have to set things up in the special __main__ module
264  PyObject *module = PyImport_AddModule(PyCC("__main__"));
265  if (module == NULL)
266  panic("Could not import __main__");
267  PyObject *dict = PyModule_GetDict(module);
268 
269  // import the main m5 module
270  PyObject *result;
271  const char **command = m5MainCommands;
272 
273  // evaluate each command in the m5MainCommands array (basically a
274  // bunch of python statements.
275  while (*command) {
276  result = PyRun_String(*command, Py_file_input, dict, dict);
277  if (!result) {
278  PyErr_Print();
279  return 1;
280  }
281  Py_DECREF(result);
282 
283  command++;
284  }
285 
286 #if HAVE_PROTOBUF
287  google::protobuf::ShutdownProtobufLibrary();
288 #endif
289 
290  return 0;
291 }
292 
293 PyMODINIT_FUNC
294 initm5(void)
295 {
296  initM5Python();
297  PyImport_ImportModule(PyCC("m5"));
298 }
int m5Main(int argc, char **argv)
Definition: init.cc:252
void pybind_init_core(py::module &m_native)
Definition: core.cc:205
static std::list< EmbeddedPython * > & getList()
Definition: init.cc:91
void pybind_init_stats(pybind11::module &m_native)
const char * abspath
Definition: init.hh:65
bool addModule() const
Definition: init.cc:115
const std::string & name()
Definition: trace.cc:49
Bitfield< 7 > i
Definition: miscregs.hh:1378
Bitfield< 0 > m
Definition: miscregs.hh:1577
#define panic(...)
Definition: misc.hh:153
This file defines flags used to handle asynchronous simulator events.
const uint8_t * code
Definition: init.hh:67
bool registered
Definition: init.hh:101
const char * __attribute__((weak)) m5MainCommands[]
static void initAll()
Definition: init.cc:194
bool depsReady() const
Definition: init.cc:181
static EmbeddedPython * importer
Definition: init.hh:77
int zlen
Definition: init.hh:68
const char * modpath
Definition: init.hh:66
void(* initFunc)(pybind11::module &)
Definition: init.hh:96
static std::map< std::string, EmbeddedPyBind * > & getMap()
Definition: init.cc:187
void init(pybind11::module &m)
Definition: init.cc:170
void pybind_init_pyobject(pybind11::module &m_native)
const char * filename
Definition: init.hh:64
const char * m5MainCommands[]
Definition: stattest.cc:48
const std::string name
Definition: init.hh:102
PyObject * getCode() const
Definition: init.cc:102
static PyObject * importerModule
Definition: init.hh:78
_object PyObject
Definition: init.hh:55
Bitfield< 51, 12 > base
Definition: pagetable.hh:85
STL list class.
Definition: stl.hh:54
Defines global host-dependent types: Counter, Tick, and (indirectly) {int,uint}{8,16,32,64}_t.
#define PyCC(x)
Definition: init.cc:73
void pybind_init_debug(py::module &m_native)
Definition: debug.cc:82
EmbeddedPython(const char *filename, const char *abspath, const char *modpath, const uint8_t *code, int zlen, int len)
Definition: init.cc:77
Bitfield< 18, 16 > len
Definition: miscregs.hh:1626
static int initAll()
Definition: init.cc:133
const std::string base
Definition: init.hh:103
int initM5Python()
Definition: init.cc:231
void pybind_init_event(py::module &m_native)
Definition: event.cc:105
PyMODINIT_FUNC initm5(void)
Definition: init.cc:294
void cprintf(const char *format, const Args &...args)
Definition: cprintf.hh:155
EmbeddedPyBind(const char *_name, void(*init_func)(pybind11::module &), const char *_base)

Generated on Fri Jun 9 2017 13:03:51 for gem5 by doxygen 1.8.6