113404Sgabeblack@google.com/*
213404Sgabeblack@google.com * Copyright 2018 Google, Inc.
313404Sgabeblack@google.com *
413404Sgabeblack@google.com * Redistribution and use in source and binary forms, with or without
513404Sgabeblack@google.com * modification, are permitted provided that the following conditions are
613404Sgabeblack@google.com * met: redistributions of source code must retain the above copyright
713404Sgabeblack@google.com * notice, this list of conditions and the following disclaimer;
813404Sgabeblack@google.com * redistributions in binary form must reproduce the above copyright
913404Sgabeblack@google.com * notice, this list of conditions and the following disclaimer in the
1013404Sgabeblack@google.com * documentation and/or other materials provided with the distribution;
1113404Sgabeblack@google.com * neither the name of the copyright holders nor the names of its
1213404Sgabeblack@google.com * contributors may be used to endorse or promote products derived from
1313404Sgabeblack@google.com * this software without specific prior written permission.
1413404Sgabeblack@google.com *
1513404Sgabeblack@google.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1613404Sgabeblack@google.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
1713404Sgabeblack@google.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
1813404Sgabeblack@google.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
1913404Sgabeblack@google.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2013404Sgabeblack@google.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2113404Sgabeblack@google.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2213404Sgabeblack@google.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2313404Sgabeblack@google.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2413404Sgabeblack@google.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2513404Sgabeblack@google.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2613404Sgabeblack@google.com *
2713404Sgabeblack@google.com * Authors: Gabe Black
2813404Sgabeblack@google.com */
2913404Sgabeblack@google.com
3013411Sgiacomo.travaglini@arm.com// This should be on top since it is including python headers
3113411Sgiacomo.travaglini@arm.com#include "systemc/core/python.hh"
3213411Sgiacomo.travaglini@arm.com
3313404Sgabeblack@google.com#include <cstring>
3413404Sgabeblack@google.com#include <string>
3513404Sgabeblack@google.com
3613404Sgabeblack@google.com#include "base/fiber.hh"
3713404Sgabeblack@google.com#include "base/logging.hh"
3813404Sgabeblack@google.com#include "systemc/core/sc_main_fiber.hh"
3913404Sgabeblack@google.com
4013404Sgabeblack@google.comnamespace
4113404Sgabeblack@google.com{
4213404Sgabeblack@google.com
4313404Sgabeblack@google.com// This wrapper adapts the python version of sc_main to the c++ version.
4413404Sgabeblack@google.comvoid
4513404Sgabeblack@google.comsc_main(pybind11::args args)
4613404Sgabeblack@google.com{
4713404Sgabeblack@google.com    panic_if(::sc_gem5::scMainFiber.called(),
4813404Sgabeblack@google.com            "sc_main called more than once.");
4913404Sgabeblack@google.com
5013404Sgabeblack@google.com    int argc = args.size();
5113404Sgabeblack@google.com    char **argv = new char *[argc];
5213404Sgabeblack@google.com
5313404Sgabeblack@google.com    // Initialize all the argvs to NULL so we can delete [] them
5413404Sgabeblack@google.com    // unconditionally.
5513404Sgabeblack@google.com    for (int idx = 0; idx < argc; idx++)
5613404Sgabeblack@google.com        argv[idx] = NULL;
5713404Sgabeblack@google.com
5813404Sgabeblack@google.com    // Attempt to convert all the arguments to strings. If that fails, clean
5913404Sgabeblack@google.com    // up after ourselves. Also don't count this as a call to sc_main since
6013404Sgabeblack@google.com    // we never got to the c++ version of that function.
6113404Sgabeblack@google.com    try {
6213404Sgabeblack@google.com        for (int idx = 0; idx < argc; idx++) {
6313404Sgabeblack@google.com            std::string arg = args[idx].cast<std::string>();
6413404Sgabeblack@google.com            argv[idx] = new char[arg.length() + 1];
6513404Sgabeblack@google.com            strcpy(argv[idx], arg.c_str());
6613404Sgabeblack@google.com        }
6713404Sgabeblack@google.com    } catch (...) {
6813404Sgabeblack@google.com        // If that didn't work for some reason (probably a conversion error)
6913404Sgabeblack@google.com        // blow away argv and argc and pass on the exception.
7013404Sgabeblack@google.com        for (int idx = 0; idx < argc; idx++)
7113404Sgabeblack@google.com            delete [] argv[idx];
7213404Sgabeblack@google.com        delete [] argv;
7313404Sgabeblack@google.com        argc = 0;
7413404Sgabeblack@google.com        throw;
7513404Sgabeblack@google.com    }
7613404Sgabeblack@google.com
7713404Sgabeblack@google.com    ::sc_gem5::scMainFiber.setArgs(argc, argv);
7813404Sgabeblack@google.com    ::sc_gem5::scMainFiber.run();
7913404Sgabeblack@google.com}
8013404Sgabeblack@google.com
8113404Sgabeblack@google.comint
8213404Sgabeblack@google.comsc_main_result_code()
8313404Sgabeblack@google.com{
8413404Sgabeblack@google.com    return ::sc_gem5::scMainFiber.resultInt();
8513404Sgabeblack@google.com}
8613404Sgabeblack@google.com
8713404Sgabeblack@google.comstd::string
8813404Sgabeblack@google.comsc_main_result_str()
8913404Sgabeblack@google.com{
9013404Sgabeblack@google.com    return ::sc_gem5::scMainFiber.resultStr();
9113404Sgabeblack@google.com}
9213404Sgabeblack@google.com
9313404Sgabeblack@google.com// Make our sc_main wrapper available in the internal _m5 python module under
9413404Sgabeblack@google.com// the systemc submodule.
9513404Sgabeblack@google.com
9613404Sgabeblack@google.comstruct InstallScMain : public ::sc_gem5::PythonInitFunc
9713404Sgabeblack@google.com{
9813404Sgabeblack@google.com    void
9913404Sgabeblack@google.com    run(pybind11::module &systemc) override
10013404Sgabeblack@google.com    {
10113404Sgabeblack@google.com        systemc.def("sc_main", &sc_main);
10213404Sgabeblack@google.com        systemc.def("sc_main_result_code", &sc_main_result_code);
10313404Sgabeblack@google.com        systemc.def("sc_main_result_str", &sc_main_result_str);
10413404Sgabeblack@google.com    }
10513404Sgabeblack@google.com} installScMain;
10613404Sgabeblack@google.com
10713404Sgabeblack@google.com} // anonymous namespace
108