Remove SWIG-specific Python code.
Change-Id: If1d1b253d84021c9a8f9a64027ea7a94f2336dff
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Andreas Hansson <andreas.hansson@arm.com>
Reviewed-by: Curtis Dunham <curtis.dunham@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/2922
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Reviewed-by: Tony Gutierrez <anthony.gutierrez@amd.com>
noCxxHeader = True
warn("No header file specified for SimObject: %s", name)
- # Export methods are automatically inherited via C++, so we
- # don't want the method declarations to get inherited on the
- # python side (and thus end up getting repeated in the wrapped
- # versions of derived classes). The code below basicallly
- # suppresses inheritance by substituting in the base (null)
- # versions of these methods unless a different version is
- # explicitly supplied.
- for method_name in ('export_methods', 'export_method_swig_predecls'):
- if method_name not in cls.__dict__:
- base_method = getattr(MetaSimObject, method_name)
- m = MethodType(base_method, cls, MetaSimObject)
- setattr(cls, method_name, m)
-
# Now process the _value_dict items. They could be defining
# new (or overriding existing) parameters or ports, setting
# class keywords (e.g., 'abstract'), or setting parameter
def pybind_predecls(cls, code):
code('#include "${{cls.cxx_header}}"')
- # See ParamValue.swig_predecls for description.
- def swig_predecls(cls, code):
- code('%import "python/_m5/param_$cls.i"')
-
- # Hook for exporting additional C++ methods to Python via SWIG.
- # Default is none, override using @classmethod in class definition.
- def export_methods(cls, code):
- pass
-
- # Generate the code needed as a prerequisite for the C++ methods
- # exported via export_methods() to be processed by SWIG.
- # Typically generates one or more %include or %import statements.
- # If any methods are exported, typically at least the C++ header
- # declaring the relevant SimObject class must be included.
- def export_method_swig_predecls(cls, code):
- pass
-
- # Generate the declaration for this object for wrapping with SWIG.
- # Generates code that goes into a SWIG .i file. Called from
- # src/SConscript.
- def swig_decl(cls, code):
- class_path = cls.cxx_class.split('::')
- classname = class_path[-1]
- namespaces = class_path[:-1]
-
- # The 'local' attribute restricts us to the params declared in
- # the object itself, not including inherited params (which
- # will also be inherited from the base class's param struct
- # here). Sort the params based on their key
- params = map(lambda (k, v): v, sorted(cls._params.local.items()))
- ports = cls._ports.local
-
- code('%module(package="_m5") param_$cls')
- code()
- code('%{')
- code('#include "sim/sim_object.hh"')
- code('#include "params/$cls.hh"')
- for param in params:
- param.cxx_predecls(code)
- code('#include "${{cls.cxx_header}}"')
- code('''\
-/**
- * This is a workaround for bug in swig. Prior to gcc 4.6.1 the STL
- * headers like vector, string, etc. used to automatically pull in
- * the cstddef header but starting with gcc 4.6.1 they no longer do.
- * This leads to swig generated a file that does not compile so we
- * explicitly include cstddef. Additionally, including version 2.0.4,
- * swig uses ptrdiff_t without the std:: namespace prefix which is
- * required with gcc 4.6.1. We explicitly provide access to it.
- */
-#include <cstddef>
-using std::ptrdiff_t;
-''')
- code('%}')
- code()
-
- for param in params:
- param.swig_predecls(code)
- cls.export_method_swig_predecls(code)
-
- code()
- if cls._base:
- code('%import "python/_m5/param_${{cls._base}}.i"')
- code()
-
- for ns in namespaces:
- code('namespace $ns {')
-
- if namespaces:
- code('// avoid name conflicts')
- sep_string = '_COLONS_'
- flat_name = sep_string.join(class_path)
- code('%rename($flat_name) $classname;')
-
- code()
- code('// stop swig from creating/wrapping default ctor/dtor')
- code('%nodefault $classname;')
- code('class $classname')
- if cls._base:
- bases = [ cls._base.cxx_class ] + cls.cxx_bases
- else:
- bases = cls.cxx_bases
- base_first = True
- for base in bases:
- if base_first:
- code(' : public ${{base}}')
- base_first = False
- else:
- code(' , public ${{base}}')
-
- code('{')
- code(' public:')
- cls.export_methods(code)
- code('};')
-
- for ns in reversed(namespaces):
- code('} // namespace $ns')
-
- code()
- code('%include "params/$cls.hh"')
-
def pybind_decl(cls, code):
class_path = cls.cxx_class.split('::')
namespaces, classname = class_path[:-1], class_path[-1]
cxx_bases = [ "Drainable", "Serializable" ]
eventq_index = Param.UInt32(Parent.eventq_index, "Event Queue Index")
- @classmethod
- def export_method_swig_predecls(cls, code):
- code('''
-%include <std_string.i>
-
-%import "python/swig/drain.i"
-%import "python/swig/serialize.i"
-''')
-
- @classmethod
- def export_methods(cls, code):
- code('''
- void init();
- void loadState(CheckpointIn &cp);
- void initState();
- void memInvalidate();
- void memWriteback();
- void regStats();
- void resetStats();
- void regProbePoints();
- void regProbeListeners();
- void startup();
-''')
-
cxx_exports = [
PyBindMethod("init"),
PyBindMethod("initState"),
# If the attribute exists on the C++ object, transparently
# forward the reference there. This is typically used for
- # SWIG-wrapped methods such as init(), regStats(),
- # resetStats(), startup(), drain(), and
- # resume().
+ # methods exported to Python (e.g., init(), and startup())
if self._ccObject and hasattr(self._ccObject, attr):
return getattr(self._ccObject, attr)
# scripts while allowing new SCons code to operate properly.
try:
- # Try to import something that's generated by swig
+ # Try to import a native module
import _m5.core
# Try to grab something from it in case demandimport is being used
def pybind_predecls(cls, code):
cls.cxx_predecls(code)
- # Generate the code needed as a prerequisite for including a
- # reference to a C++ object of this type in a SWIG .i file.
- # Typically generates one or more %import or %include statements.
- @classmethod
- def swig_predecls(cls, code):
- pass
-
# default for printing to .ini file is regular string conversion.
# will be overridden in some cases
def ini_str(self):
def pybind_predecls(self, code):
self.ptype.pybind_predecls(code)
- def swig_predecls(self, code):
- self.ptype.swig_predecls(code)
-
def cxx_decl(self, code):
code('${{self.ptype.cxx_type}} ${{self.name}};')
return VectorParamValue(tmp_list)
- def swig_module_name(self):
- return "%s_vector" % self.ptype_str
-
- def swig_predecls(self, code):
- code('%import "${{self.swig_module_name()}}.i"')
-
- def swig_decl(self, code):
- code('%module(package="_m5") ${{self.swig_module_name()}}')
- code('%{')
- self.ptype.cxx_predecls(code)
- code('%}')
- code()
- # Make sure the SWIGPY_SLICE_ARG is defined through this inclusion
- code('%include "std_container.i"')
- code()
- self.ptype.swig_predecls(code)
- code()
- code('%include "std_vector.i"')
- code()
-
- ptype = self.ptype_str
- cxx_type = self.ptype.cxx_type
-
- code('%template(vector_$ptype) std::vector< $cxx_type >;')
-
def cxx_predecls(self, code):
code('#include <vector>')
self.ptype.cxx_predecls(code)
def cxx_predecls(self, code):
code('#include <string>')
- @classmethod
- def swig_predecls(cls, code):
- code('%include "std_string.i"')
-
def __call__(self, value):
self = value
return value
# most derived types require this, so we just do it here once
code('#include "base/types.hh"')
- @classmethod
- def swig_predecls(cls, code):
- # most derived types require this, so we just do it here once
- code('%import "stdint.i"')
- code('%import "base/types.hh"')
-
def getValue(self):
return long(self.value)
Addr.pybind_predecls(code)
code('#include "base/addr_range.hh"')
- @classmethod
- def swig_predecls(cls, code):
- Addr.swig_predecls(code)
-
@classmethod
def cxx_ini_predecls(cls, code):
code('#include <sstream>')
code('${ret} _ret;')
def getValue(self):
- # Go from the Python class to the wrapped C++ class generated
- # by swig
+ # Go from the Python class to the wrapped C++ class
from _m5.range import AddrRange
return AddrRange(long(self.start), long(self.end),
def cxx_predecls(cls, code):
code('#include "base/inet.hh"')
- @classmethod
- def swig_predecls(cls, code):
- code('%include "python/swig/inet.i"')
-
def __init__(self, value):
if value == NextEthernetAddr:
self.value = value
def cxx_predecls(cls, code):
code('#include "base/inet.hh"')
- @classmethod
- def swig_predecls(cls, code):
- code('%include "python/swig/inet.i"')
-
def __init__(self, value):
if isinstance(value, IpAddress):
self.ip = value.ip
def cxx_predecls(cls, code):
code('#include "base/inet.hh"')
- @classmethod
- def swig_predecls(cls, code):
- code('%include "python/swig/inet.i"')
-
def __init__(self, *args, **kwargs):
def handle_kwarg(self, kwargs, key, elseVal = None):
if key in kwargs:
def cxx_predecls(cls, code):
code('#include "base/inet.hh"')
- @classmethod
- def swig_predecls(cls, code):
- code('%include "python/swig/inet.i"')
-
def __init__(self, *args, **kwargs):
def handle_kwarg(self, kwargs, key, elseVal = None):
if key in kwargs:
def cxx_predecls(cls, code):
code('#include <time.h>')
- @classmethod
- def swig_predecls(cls, code):
- code('%include "python/swig/time.i"')
-
def __init__(self, value):
self.value = parse_time(value)
code()
code('static EmbeddedPyBind embed_enum("enum_${name}", module_init);')
- def swig_decl(cls, code):
- name = cls.__name__
- code('''\
-%module(package="_m5") enum_$name
-
-%{
-#include "enums/$name.hh"
-%}
-
-%include "enums/$name.hh"
-''')
-
# Base class for enum types.
class Enum(ParamValue):
def cxx_predecls(cls, code):
code('#include "enums/$0.hh"', cls.__name__)
- @classmethod
- def swig_predecls(cls, code):
- code('%import "python/_m5/enum_$0.i"', cls.__name__)
-
@classmethod
def cxx_ini_parse(cls, code, src, dest, ret):
code('if (false) {')
def cxx_predecls(cls, code):
code('#include "base/types.hh"')
- @classmethod
- def swig_predecls(cls, code):
- code('%import "stdint.i"')
- code('%import "base/types.hh"')
-
def __call__(self, value):
self.__init__(value)
return value
import os
import sys
-# import the SWIG-wrapped main C++ functions
+# import the wrapped C++ functions
import _m5.drain
import _m5.core
from _m5.stats import updateEvents as updateStatEvents
#endif
/**
- * Connect the described MemObject ports. Called from Python via SWIG.
+ * Connect the described MemObject ports. Called from Python.
* The indices i1 & i2 will be -1 for regular ports, >= 0 for vector ports.
* SimObject1 is the master, and SimObject2 is the slave
*/