sc_main.cc revision 12837
14309Sgblack@eecs.umich.edu/*
24309Sgblack@eecs.umich.edu * Copyright 2018 Google, Inc.
35426Sgblack@eecs.umich.edu *
44309Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without
54309Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are
64309Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright
74309Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer;
84309Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright
94309Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the
104309Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution;
114309Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its
124309Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from
134309Sgblack@eecs.umich.edu * this software without specific prior written permission.
144309Sgblack@eecs.umich.edu *
154309Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
164309Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
174309Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
184309Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
194309Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
204309Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
214309Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
224309Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
234309Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
244309Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
254309Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
264309Sgblack@eecs.umich.edu *
274309Sgblack@eecs.umich.edu * Authors: Gabe Black
284309Sgblack@eecs.umich.edu */
294309Sgblack@eecs.umich.edu
304309Sgblack@eecs.umich.edu#include <cstring>
314309Sgblack@eecs.umich.edu
324309Sgblack@eecs.umich.edu#include "base/logging.hh"
334309Sgblack@eecs.umich.edu#include "python/pybind11/pybind.hh"
344309Sgblack@eecs.umich.edu#include "sim/init.hh"
354309Sgblack@eecs.umich.edu#include "systemc/ext/core/sc_main.hh"
364309Sgblack@eecs.umich.edu
374309Sgblack@eecs.umich.edu// A default version of this function in case one isn't otherwise defined.
384309Sgblack@eecs.umich.edu// This ensures everything will link properly whether or not the user defined
394309Sgblack@eecs.umich.edu// a custom sc_main function. If they didn't but still try to call it, throw
404309Sgblack@eecs.umich.edu// an error and die.
414309Sgblack@eecs.umich.edu[[gnu::weak]] int
424309Sgblack@eecs.umich.edusc_main(int argc, char *argv[])
434309Sgblack@eecs.umich.edu{
444309Sgblack@eecs.umich.edu    // If python attempts to call sc_main but no sc_main was defined...
454309Sgblack@eecs.umich.edu    fatal("sc_main called but not defined.\n");
464309Sgblack@eecs.umich.edu}
474309Sgblack@eecs.umich.edu
484309Sgblack@eecs.umich.edunamespace sc_core
494309Sgblack@eecs.umich.edu{
504309Sgblack@eecs.umich.edu
514309Sgblack@eecs.umich.edunamespace
524309Sgblack@eecs.umich.edu{
534309Sgblack@eecs.umich.edu
544309Sgblack@eecs.umich.edubool scMainCalled = false;
554309Sgblack@eecs.umich.edu
564309Sgblack@eecs.umich.eduint _argc = 0;
574309Sgblack@eecs.umich.educhar **_argv = NULL;
584533Sgblack@eecs.umich.edu
594679Sgblack@eecs.umich.edu// This wrapper adapts the python version of sc_main to the c++ version.
604679Sgblack@eecs.umich.eduvoid
614679Sgblack@eecs.umich.edusc_main(pybind11::args args)
624533Sgblack@eecs.umich.edu{
634533Sgblack@eecs.umich.edu    panic_if(scMainCalled, "sc_main called more than once.");
644537Sgblack@eecs.umich.edu
654533Sgblack@eecs.umich.edu    _argc = args.size();
664528Sgblack@eecs.umich.edu    _argv = new char *[_argc];
675666Sgblack@eecs.umich.edu
685666Sgblack@eecs.umich.edu    // Initialize all the _argvs to NULL so we can delete [] them
695666Sgblack@eecs.umich.edu    // unconditionally.
704528Sgblack@eecs.umich.edu    for (int idx = 0; idx < _argc; idx++)
714528Sgblack@eecs.umich.edu        _argv[idx] = NULL;
724528Sgblack@eecs.umich.edu
734528Sgblack@eecs.umich.edu    // Attempt to convert all the arguments to strings. If that fails, clean
744605Sgblack@eecs.umich.edu    // up after ourselves. Also don't count this as a call to sc_main since
755666Sgblack@eecs.umich.edu    // we never got to the c++ version of that function.
765666Sgblack@eecs.umich.edu    try {
774528Sgblack@eecs.umich.edu        for (int idx = 0; idx < _argc; idx++) {
784615Sgblack@eecs.umich.edu            std::string arg = args[idx].cast<std::string>();
795854Sgblack@eecs.umich.edu            _argv[idx] = new char[arg.length() + 1];
804615Sgblack@eecs.umich.edu            strcpy(_argv[idx], arg.c_str());
815854Sgblack@eecs.umich.edu        }
825045Sgblack@eecs.umich.edu    } catch (...) {
834615Sgblack@eecs.umich.edu        // If that didn't work for some reason (probably a conversion error)
845671Sgblack@eecs.umich.edu        // blow away _argv and _argc and pass on the exception.
854615Sgblack@eecs.umich.edu        for (int idx = 0; idx < _argc; idx++)
865291Sgblack@eecs.umich.edu            delete [] _argv[idx];
875428Sgblack@eecs.umich.edu        delete [] _argv;
885674Sgblack@eecs.umich.edu        _argc = 0;
895899Sgblack@eecs.umich.edu        throw;
905900Sgblack@eecs.umich.edu    }
915428Sgblack@eecs.umich.edu
925428Sgblack@eecs.umich.edu    // At this point we're going to call the c++ sc_main, so we can't try
935294Sgblack@eecs.umich.edu    // again later.
945291Sgblack@eecs.umich.edu    scMainCalled = true;
955291Sgblack@eecs.umich.edu
965294Sgblack@eecs.umich.edu    //TODO Start a new fiber to call sc_main from.
975294Sgblack@eecs.umich.edu    ::sc_main(_argc, _argv);
985294Sgblack@eecs.umich.edu}
994615Sgblack@eecs.umich.edu
1004615Sgblack@eecs.umich.edu// Make our sc_main wrapper available in the internal _m5 python module under
1014615Sgblack@eecs.umich.edu// the systemc submodule.
1025029Sgblack@eecs.umich.eduvoid
1035029Sgblack@eecs.umich.edusystemc_pybind(pybind11::module &m_internal)
1044615Sgblack@eecs.umich.edu{
1055029Sgblack@eecs.umich.edu    pybind11::module m = m_internal.def_submodule("systemc");
1065029Sgblack@eecs.umich.edu    m.def("sc_main", &sc_main);
1075161Sgblack@eecs.umich.edu}
1085161Sgblack@eecs.umich.eduEmbeddedPyBind embed_("systemc", &systemc_pybind);
1094863Sgblack@eecs.umich.edu
1104615Sgblack@eecs.umich.edu} // anonymous namespace
1114615Sgblack@eecs.umich.edu
1124615Sgblack@eecs.umich.eduint
1134615Sgblack@eecs.umich.edusc_argc()
1144953Sgblack@eecs.umich.edu{
1154615Sgblack@eecs.umich.edu    return _argc;
1164615Sgblack@eecs.umich.edu}
1174863Sgblack@eecs.umich.edu
1184863Sgblack@eecs.umich.educonst char *const *
1195326Sgblack@eecs.umich.edusc_argv()
1205326Sgblack@eecs.umich.edu{
1215326Sgblack@eecs.umich.edu    return _argv;
1225326Sgblack@eecs.umich.edu}
1235326Sgblack@eecs.umich.edu
1245326Sgblack@eecs.umich.edu} // namespace sc_core
1255326Sgblack@eecs.umich.edu