From 0536d0cde931e89d33b10228950d455dd54d8a5f Mon Sep 17 00:00:00 2001 From: Nathan Binkert Date: Thu, 2 Aug 2007 22:50:02 -0700 Subject: python: Improve support for python calling back to C++ member functions. Add support for declaring SimObjects to swig so their members can be wrapped. Make sim_object.i only contain declarations for SimObject. Create system.i to contain declarations for System. Update python code to properly call the C++ given the new changes. --HG-- extra : convert_revision : 82076ee69e8122d56e91b92d6767e356baae420a --- src/python/m5/SimObject.py | 42 ++++++++++++++++---------------------- src/python/m5/internal/__init__.py | 1 - src/python/m5/params.py | 6 +++--- src/python/m5/simulate.py | 16 +++++++-------- 4 files changed, 29 insertions(+), 36 deletions(-) (limited to 'src/python/m5') diff --git a/src/python/m5/SimObject.py b/src/python/m5/SimObject.py index 1e7d289e2..22c488f5d 100644 --- a/src/python/m5/SimObject.py +++ b/src/python/m5/SimObject.py @@ -128,6 +128,7 @@ class MetaSimObject(type): 'cxx_class' : types.StringType, 'cxx_type' : types.StringType, 'cxx_predecls' : types.ListType, + 'swig_objdecls' : types.ListType, 'swig_predecls' : types.ListType, 'type' : types.StringType } # Attributes that can be set any time @@ -225,6 +226,9 @@ class MetaSimObject(type): cls._value_dict['swig_predecls'] = \ cls._value_dict['cxx_predecls'] + if 'swig_objdecls' not in cls._value_dict: + cls._value_dict['swig_objdecls'] = [] + # 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 @@ -345,12 +349,13 @@ class MetaSimObject(type): def __str__(cls): return cls.__name__ - def cxx_decl(cls): - if str(cls) != 'SimObject': - base = cls.__bases__[0].type - else: - base = None + def get_base(cls): + if str(cls) == 'SimObject': + return None + + return cls.__bases__[0].type + def cxx_decl(cls): code = "#ifndef __PARAMS__%s\n" % cls code += "#define __PARAMS__%s\n\n" % cls @@ -380,6 +385,7 @@ class MetaSimObject(type): code += "\n".join(predecls2) code += "\n\n"; + base = cls.get_base() if base: code += '#include "params/%s.hh"\n\n' % base @@ -408,11 +414,7 @@ class MetaSimObject(type): return code def cxx_type_decl(cls): - if str(cls) != 'SimObject': - base = cls.__bases__[0] - else: - base = None - + base = cls.get_base() code = '' if base: @@ -427,17 +429,14 @@ class MetaSimObject(type): return code def swig_decl(cls): + base = cls.get_base() + code = '%%module %s\n' % cls code += '%{\n' code += '#include "params/%s.hh"\n' % cls code += '%}\n\n' - if str(cls) != 'SimObject': - base = cls.__bases__[0] - else: - base = None - # The 'dict' 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 @@ -483,6 +482,7 @@ class SimObject(object): abstract = True name = Param.String("Object name") + swig_objdecls = [ '%include "python/swig/sim_object.i"' ] # Initialize new instance. For objects with SimObject-valued # children, we need to recursively clone the classes represented @@ -792,7 +792,6 @@ class SimObject(object): # necessary to construct it. Does *not* recursively create # children. def getCCObject(self): - import internal params = self.getCCParams() if not self._ccObject: self._ccObject = -1 # flag to catch cycles in recursion @@ -840,24 +839,19 @@ class SimObject(object): if not isinstance(self, m5.objects.System): return None - system_ptr = internal.sim_object.convertToSystemPtr(self._ccObject) - return system_ptr.getMemoryMode() + return self._ccObject.getMemoryMode() def changeTiming(self, mode): - import internal if isinstance(self, m5.objects.System): # i don't know if there's a better way to do this - calling # setMemoryMode directly from self._ccObject results in calling # SimObject::setMemoryMode, not the System::setMemoryMode - system_ptr = internal.sim_object.convertToSystemPtr(self._ccObject) - system_ptr.setMemoryMode(mode) + self._ccObject.setMemoryMode(mode) for child in self._children.itervalues(): child.changeTiming(mode) def takeOverFrom(self, old_cpu): - import internal - cpu_ptr = internal.sim_object.convertToBaseCPUPtr(old_cpu._ccObject) - self._ccObject.takeOverFrom(cpu_ptr) + self._ccObject.takeOverFrom(old_cpu._ccObject) # generate output file for 'dot' to display as a pretty graph. # this code is currently broken. diff --git a/src/python/m5/internal/__init__.py b/src/python/m5/internal/__init__.py index 6b7859cd7..4aa76cca7 100644 --- a/src/python/m5/internal/__init__.py +++ b/src/python/m5/internal/__init__.py @@ -30,6 +30,5 @@ import core import debug import event import random -import sim_object import stats import trace diff --git a/src/python/m5/params.py b/src/python/m5/params.py index 3fca4e97a..df70bf469 100644 --- a/src/python/m5/params.py +++ b/src/python/m5/params.py @@ -1025,13 +1025,13 @@ class PortRef(object): # Call C++ to create corresponding port connection between C++ objects def ccConnect(self): - import internal + from m5.objects.params import connectPorts if self.ccConnected: # already done this return peer = self.peer - internal.sim_object.connectPorts(self.simobj.getCCObject(), self.name, - self.index, peer.simobj.getCCObject(), peer.name, peer.index) + connectPorts(self.simobj.getCCObject(), self.name, self.index, + peer.simobj.getCCObject(), peer.name, peer.index) self.ccConnected = True peer.ccConnected = True diff --git a/src/python/m5/simulate.py b/src/python/m5/simulate.py index ba9fb7899..c703664d4 100644 --- a/src/python/m5/simulate.py +++ b/src/python/m5/simulate.py @@ -59,10 +59,10 @@ def instantiate(root): root.connectPorts() # Do a second pass to finish initializing the sim objects - internal.sim_object.initAll() + internal.core.initAll() # Do a third pass to initialize statistics - internal.sim_object.regAllStats() + internal.core.regAllStats() # Check to make sure that the stats package is properly initialized internal.stats.check() @@ -136,32 +136,32 @@ def checkpoint(root, dir): raise TypeError, "Checkpoint must be called on a root object." doDrain(root) print "Writing checkpoint" - internal.sim_object.serializeAll(dir) + internal.core.serializeAll(dir) resume(root) def restoreCheckpoint(root, dir): print "Restoring from checkpoint" - internal.sim_object.unserializeAll(dir) + internal.core.unserializeAll(dir) need_resume.append(root) def changeToAtomic(system): if not isinstance(system, (objects.Root, objects.System)): raise TypeError, "Parameter of type '%s'. Must be type %s or %s." % \ (type(system), objects.Root, objects.System) - if system.getMemoryMode() != internal.sim_object.SimObject.Atomic: + if system.getMemoryMode() != objects.params.SimObject.Atomic: doDrain(system) print "Changing memory mode to atomic" - system.changeTiming(internal.sim_object.SimObject.Atomic) + system.changeTiming(objects.params.SimObject.Atomic) def changeToTiming(system): if not isinstance(system, (objects.Root, objects.System)): raise TypeError, "Parameter of type '%s'. Must be type %s or %s." % \ (type(system), objects.Root, objects.System) - if system.getMemoryMode() != internal.sim_object.SimObject.Timing: + if system.getMemoryMode() != objects.params.SimObject.Timing: doDrain(system) print "Changing memory mode to timing" - system.changeTiming(internal.sim_object.SimObject.Timing) + system.changeTiming(objects.params.SimObject.Timing) def switchCpus(cpuList): print "switching cpus" -- cgit v1.2.3