changeset e6e22fa77883 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=e6e22fa77883
description:
        scons/swig: refactor some of the scons/SWIG code

        - Move the random bits of SWIG code generation out of src/SConscript
          file and into methods on the objects being wrapped.
        - Cleaned up some variable naming and added some comments to make
          the process a little clearer.
        - Did a little generated file/module renaming:
           - vptype_Foo now Foo_vector
           - init_Foo is now Foo_init
          This makes it easier to see all the Foo-related files in a
          sorted directory listing.
        - Made cxx_predecls and swig_predecls normal SimObject classmethods.
        - Got rid of swig_objdecls hook, even though this breaks the System
          objects get/setMemoryMode method exports.  Will be fixing this in
          a future changeset.

diffstat:

 src/SConscript             |  105 +++++++++---------------
 src/python/m5/SimObject.py |  192 ++++++++++++++++++++------------------------
 src/python/m5/params.py    |   30 +++++-
 src/sim/System.py          |    2 +
 4 files changed, 153 insertions(+), 176 deletions(-)

diffs (truncated from 528 to 300 lines):

diff -r 1f3c96b5d85e -r e6e22fa77883 src/SConscript
--- a/src/SConscript    Wed Oct 19 18:08:31 2011 -0500
+++ b/src/SConscript    Thu Oct 20 13:08:49 2011 -0700
@@ -449,7 +449,13 @@
 sim_objects = m5.SimObject.allClasses
 all_enums = m5.params.allEnums
 
-all_params = {}
+# Find param types that need to be explicitly wrapped with swig.
+# These will be recognized because the ParamDesc will have a
+# swig_decl() method.  Most param types are based on types that don't
+# need this, either because they're based on native types (like Int)
+# or because they're SimObjects (which get swigged independently).
+# For now the only things handled here are VectorParam types.
+params_to_swig = {}
 for name,obj in sorted(sim_objects.iteritems()):
     for param in obj._params.local.values():
         # load the ptype attribute now because it depends on the
@@ -461,8 +467,8 @@
         if not hasattr(param, 'swig_decl'):
             continue
         pname = param.ptype_str
-        if pname not in all_params:
-            all_params[pname] = param
+        if pname not in params_to_swig:
+            params_to_swig[pname] = param
 
 ########################################################################
 #
@@ -523,24 +529,23 @@
 # Create all of the SimObject param headers and enum headers
 #
 
-def createSimObjectParam(target, source, env):
+def createSimObjectParamStruct(target, source, env):
     assert len(target) == 1 and len(source) == 1
 
     name = str(source[0].get_contents())
     obj = sim_objects[name]
 
     code = code_formatter()
-    obj.cxx_decl(code)
+    obj.cxx_param_decl(code)
     code.write(target[0].abspath)
 
-def createSwigParam(target, source, env):
+def createParamSwigWrapper(target, source, env):
     assert len(target) == 1 and len(source) == 1
 
     name = str(source[0].get_contents())
-    param = all_params[name]
+    param = params_to_swig[name]
 
     code = code_formatter()
-    code('%module(package="m5.internal") $0_${name}', param.file_ext)
     param.swig_decl(code)
     code.write(target[0].abspath)
 
@@ -554,7 +559,7 @@
     obj.cxx_def(code)
     code.write(target[0].abspath)
 
-def createEnumParam(target, source, env):
+def createEnumDecls(target, source, env):
     assert len(target) == 1 and len(source) == 1
 
     name = str(source[0].get_contents())
@@ -564,25 +569,25 @@
     obj.cxx_decl(code)
     code.write(target[0].abspath)
 
-def createEnumSwig(target, source, env):
+def createEnumSwigWrapper(target, source, env):
     assert len(target) == 1 and len(source) == 1
 
     name = str(source[0].get_contents())
     obj = all_enums[name]
 
     code = code_formatter()
-    code('''\
-%module(package="m5.internal") enum_$name
-
-%{
-#include "enums/$name.hh"
-%}
-
-%include "enums/$name.hh"
-''')
+    obj.swig_decl(code)
     code.write(target[0].abspath)
 
-# Generate all of the SimObject param struct header files
+def createSimObjectSwigWrapper(target, source, env):
+    name = source[0].get_contents()
+    obj = sim_objects[name]
+
+    code = code_formatter()
+    obj.swig_decl(code)
+    code.write(target[0].abspath)
+
+# Generate all of the SimObject param C++ struct header files
 params_hh_files = []
 for name,simobj in sorted(sim_objects.iteritems()):
     py_source = PySource.modules[simobj.__module__]
@@ -591,16 +596,16 @@
     hh_file = File('params/%s.hh' % name)
     params_hh_files.append(hh_file)
     env.Command(hh_file, Value(name),
-                MakeAction(createSimObjectParam, Transform("SO PARAM")))
+                MakeAction(createSimObjectParamStruct, Transform("SO PARAM")))
     env.Depends(hh_file, depends + extra_deps)
 
-# Generate any parameter header files needed
+# Generate any needed param SWIG wrapper files
 params_i_files = []
-for name,param in all_params.iteritems():
-    i_file = File('python/m5/internal/%s_%s.i' % (param.file_ext, name))
+for name,param in params_to_swig.iteritems():
+    i_file = File('python/m5/internal/%s.i' % (param.swig_module_name()))
     params_i_files.append(i_file)
     env.Command(i_file, Value(name),
-                MakeAction(createSwigParam, Transform("SW PARAM")))
+                MakeAction(createParamSwigWrapper, Transform("SW PARAM")))
     env.Depends(i_file, depends)
     SwigSource('m5.internal', i_file)
 
@@ -617,54 +622,22 @@
 
     hh_file = File('enums/%s.hh' % name)
     env.Command(hh_file, Value(name),
-                MakeAction(createEnumParam, Transform("EN PARAM")))
+                MakeAction(createEnumDecls, Transform("ENUMDECL")))
     env.Depends(hh_file, depends + extra_deps)
 
     i_file = File('python/m5/internal/enum_%s.i' % name)
     env.Command(i_file, Value(name),
-                MakeAction(createEnumSwig, Transform("ENUMSWIG")))
+                MakeAction(createEnumSwigWrapper, Transform("ENUMSWIG")))
     env.Depends(i_file, depends + extra_deps)
     SwigSource('m5.internal', i_file)
 
-def buildParam(target, source, env):
-    name = source[0].get_contents()
-    obj = sim_objects[name]
-    class_path = obj.cxx_class.split('::')
-    classname = class_path[-1]
-    namespaces = class_path[:-1]
-    params = obj._params.local.values()
-
-    code = code_formatter()
-
-    code('%module(package="m5.internal") param_$name')
-    code()
-    code('%{')
-    code('#include "params/$obj.hh"')
-    for param in params:
-        param.cxx_predecls(code)
-    code('%}')
-    code()
-
-    for param in params:
-        param.swig_predecls(code)
-
-    code()
-    if obj._base:
-        code('%import "python/m5/internal/param_${{obj._base}}.i"')
-    code()
-    obj.swig_objdecls(code)
-    code()
-
-    code('%include "params/$obj.hh"')
-
-    code.write(target[0].abspath)
-
+# Generate SimObject SWIG wrapper files
 for name in sim_objects.iterkeys():
-    params_file = File('python/m5/internal/param_%s.i' % name)
-    env.Command(params_file, Value(name),
-                MakeAction(buildParam, Transform("BLDPARAM")))
-    env.Depends(params_file, depends)
-    SwigSource('m5.internal', params_file)
+    i_file = File('python/m5/internal/param_%s.i' % name)
+    env.Command(i_file, Value(name),
+                MakeAction(createSimObjectSwigWrapper, Transform("SO SWIG")))
+    env.Depends(i_file, depends)
+    SwigSource('m5.internal', i_file)
 
 # Generate the main swig init file
 def makeEmbeddedSwigInit(target, source, env):
@@ -687,7 +660,7 @@
                 MakeAction('$SWIG $SWIGFLAGS -outdir ${TARGETS[1].dir} '
                 '-o ${TARGETS[0]} $SOURCES', Transform("SWIG")))
     cc_file = str(swig.tnode)
-    init_file = '%s/init_%s.cc' % (dirname(cc_file), basename(cc_file))
+    init_file = '%s/%s_init.cc' % (dirname(cc_file), basename(cc_file))
     env.Command(init_file, Value(swig.module),
                 MakeAction(makeEmbeddedSwigInit, Transform("EMBED SW")))
     Source(init_file, **swig.guards)
diff -r 1f3c96b5d85e -r e6e22fa77883 src/python/m5/SimObject.py
--- a/src/python/m5/SimObject.py        Wed Oct 19 18:08:31 2011 -0500
+++ b/src/python/m5/SimObject.py        Thu Oct 20 13:08:49 2011 -0700
@@ -97,37 +97,6 @@
 # dict to look up SimObjects based on path
 instanceDict = {}
 
-def default_cxx_predecls(cls, code):
-    code('#include "params/$cls.hh"')
-
-def default_swig_predecls(cls, code):
-    code('%import "python/m5/internal/param_$cls.i"')
-
-def default_swig_objdecls(cls, code):
-    class_path = cls.cxx_class.split('::')
-    classname = class_path[-1]
-    namespaces = class_path[:-1]
-
-    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:
-        code('    : public ${{cls._base.cxx_class}}')
-    code('{};')
-
-    for ns in reversed(namespaces):
-        code('} // namespace $ns')
-
 def public_value(key, value):
     return key.startswith('_') or \
                isinstance(value, (FunctionType, MethodType, ModuleType,
@@ -142,9 +111,6 @@
     init_keywords = { 'abstract' : bool,
                       'cxx_class' : str,
                       'cxx_type' : str,
-                      'cxx_predecls'  : MethodType,
-                      'swig_objdecls' : MethodType,
-                      'swig_predecls' : MethodType,
                       'type' : str }
     # Attributes that can be set any time
     keywords = { 'check' : FunctionType }
@@ -223,18 +189,6 @@
                 cls._value_dict['cxx_class'] = cls._value_dict['type']
 
             cls._value_dict['cxx_type'] = '%s *' % cls._value_dict['cxx_class']
-                
-            if 'cxx_predecls' not in cls.__dict__:
-                m = MethodType(default_cxx_predecls, cls, MetaSimObject)
-                setattr(cls, 'cxx_predecls', m)
-
-            if 'swig_predecls' not in cls.__dict__:
-                m = MethodType(default_swig_predecls, cls, MetaSimObject)
-                setattr(cls, 'swig_predecls', m)
-
-        if 'swig_objdecls' not in cls.__dict__:
-            m = MethodType(default_swig_objdecls, cls, MetaSimObject)
-            setattr(cls, 'swig_objdecls', m)
 
         # Now process the _value_dict items.  They could be defining
         # new (or overriding existing) parameters or ports, setting
@@ -378,8 +332,76 @@
     def __str__(cls):
         return cls.__name__
 
-    def cxx_decl(cls, code):
-        # The 'dict' attribute restricts us to the params declared in
+    # See ParamValue.cxx_predecls for description.
+    def cxx_predecls(cls, code):
+        code('#include "params/$cls.hh"')
+
+    # See ParamValue.swig_predecls for description.
+    def swig_predecls(cls, code):
+        code('%import "python/m5/internal/param_$cls.i"')
+
+    # 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).
+        params = cls._params.local.values()
+
+        code('%module(package="m5.internal") param_$cls')
+        code()
+        code('%{')
+        code('#include "params/$cls.hh"')
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to