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