python: Pull most of the logic in marshal.cc into python.

Put most of the logic in python, and turn the c++ parts into a very
generic wrapper which could meaningfully run any python code under the
interpreter which will be embedded in gem5.

Change-Id: I3f6e50839490eaf0db9a6bd242efbcb8de1b6e24
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/49391
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Hoa Nguyen <hoanguyen@ucdavis.edu>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Maintainer: Andreas Sandberg <andreas.sandberg@arm.com>
This commit is contained in:
Gabe Black
2021-08-14 04:32:15 -07:00
parent b0f960f765
commit 11d4ebcc5d

View File

@@ -37,19 +37,23 @@
#include <pybind11/embed.h>
#include <iostream>
namespace py = pybind11;
using namespace pybind11::literals;
constexpr auto MarshalScript = R"(
import marshal
import sys
if len(sys.argv) < 2:
print(f"Usage: {sys.argv[0]} PYSOURCE", file=sys.stderr)
sys.exit(1)
source = sys.argv[1]
with open(source, 'r') as f:
src = f.read()
compiled = compile(src, source, 'exec')
marshalled = marshal.dumps(compiled)
sys.stdout.buffer.write(marshalled)
)";
int
@@ -57,17 +61,25 @@ main(int argc, const char **argv)
{
py::scoped_interpreter guard;
if (argc != 2) {
std::cerr << "Usage: marshal PYSOURCE" << std::endl;
exit(1);
// Embedded python doesn't set up sys.argv, so we'll do that ourselves.
py::list py_argv;
auto sys = py::module::import("sys");
if (py::hasattr(sys, "argv")) {
// sys.argv already exists, so grab that.
py_argv = sys.attr("argv");
} else {
// sys.argv doesn't exist, so create it.
sys.add_object("argv", py_argv);
}
// Clear out argv just in case it has something in it.
py_argv.attr("clear")();
auto locals = py::dict("source"_a=argv[1]);
// Fill it with our argvs.
for (int i = 0; i < argc; i++)
py_argv.append(argv[i]);
py::exec(MarshalScript, py::globals(), locals);
auto marshalled = locals["marshalled"].cast<std::string>();
std::cout << marshalled;
// Actually call the script.
py::exec(MarshalScript, py::globals());
return 0;
}