From a7e8a789585193903e5fd9d07d320f5ea89b927b Mon Sep 17 00:00:00 2001
From: Steve Reinhardt <stever@eecs.umich.edu>
Date: Fri, 8 Sep 2006 19:10:11 -0400
Subject: Add support for assigning lists of ports or proxies to VectorPorts.
 Includes support for printing readable VectorPort and Proxy names (via
 __str__).

--HG--
extra : convert_revision : c48534a498b3036fe6ac45ff1606656546c79afb
---
 src/python/m5/params.py | 50 +++++++++++++++++++++++++++++++++++++++----------
 src/python/m5/proxy.py  | 12 ++++++++++++
 2 files changed, 52 insertions(+), 10 deletions(-)

(limited to 'src/python')

diff --git a/src/python/m5/params.py b/src/python/m5/params.py
index e2aea2301..cbbd23004 100644
--- a/src/python/m5/params.py
+++ b/src/python/m5/params.py
@@ -776,23 +776,25 @@ class PortRef(object):
 
     # Full connection is symmetric (both ways).  Called via
     # SimObject.__setattr__ as a result of a port assignment, e.g.,
-    # "obj1.portA = obj2.portB", or via VectorPortRef.__setitem__,
+    # "obj1.portA = obj2.portB", or via VectorPortElementRef.__setitem__,
     # e.g., "obj1.portA[3] = obj2.portB".
     def connect(self, other):
         if isinstance(other, VectorPortRef):
             # reference to plain VectorPort is implicit append
             other = other._get_next()
-        if not (isinstance(other, PortRef) or proxy.isproxy(other)):
-            raise TypeError, \
-                  "assigning non-port reference '%s' to port '%s'" \
-                  % (other, self)
         if self.peer and not proxy.isproxy(self.peer):
             print "warning: overwriting port", self, \
                   "value", self.peer, "with", other
         self.peer = other
-        assert(not isinstance(self.peer, VectorPortRef))
-        if isinstance(other, PortRef) and other.peer is not self:
-            other.connect(self)
+        if proxy.isproxy(other):
+            other.set_param_desc(PortParamDesc())
+        elif isinstance(other, PortRef):
+            if other.peer is not self:
+                other.connect(self)
+        else:
+            raise TypeError, \
+                  "assigning non-port reference '%s' to port '%s'" \
+                  % (other, self)
 
     def clone(self, simobj, memo):
         if memo.has_key(self):
@@ -847,6 +849,9 @@ class VectorPortRef(object):
         self.name = name
         self.elements = []
 
+    def __str__(self):
+        return '%s.%s[:]' % (self.simobj, self.name)
+
     # for config.ini, print peer's name (not ours)
     def ini_str(self):
         return ' '.join([el.ini_str() for el in self.elements])
@@ -870,8 +875,25 @@ class VectorPortRef(object):
         self[key].connect(value)
 
     def connect(self, other):
-        # reference to plain VectorPort is implicit append
-        self._get_next().connect(other)
+        if isinstance(other, (list, tuple)):
+            # Assign list of port refs to vector port.
+            # For now, append them... not sure if that's the right semantics
+            # or if it should replace the current vector.
+            for ref in other:
+                self._get_next().connect(ref)
+        else:
+            # scalar assignment to plain VectorPort is implicit append
+            self._get_next().connect(other)
+
+    def clone(self, simobj, memo):
+        if memo.has_key(self):
+            return memo[self]
+        newRef = copy.copy(self)
+        memo[self] = newRef
+        newRef.simobj = simobj
+        assert(isSimObject(newRef.simobj))
+        newRef.elements = [el.clone(simobj, memo) for el in self.elements]
+        return newRef
 
     def unproxy(self, simobj):
         [el.unproxy(simobj) for el in self.elements]
@@ -915,6 +937,14 @@ class VectorPort(Port):
     def makeRef(self, simobj):
         return VectorPortRef(simobj, self.name)
 
+# 'Fake' ParamDesc for Port references to assign to the _pdesc slot of
+# proxy objects (via set_param_desc()) so that proxy error messages
+# make sense.
+class PortParamDesc(object):
+    __metaclass__ = Singleton
+
+    ptype_str = 'Port'
+    ptype = Port
 
 
 __all__ = ['Param', 'VectorParam',
diff --git a/src/python/m5/proxy.py b/src/python/m5/proxy.py
index 36995397b..7ebc0ae19 100644
--- a/src/python/m5/proxy.py
+++ b/src/python/m5/proxy.py
@@ -39,6 +39,15 @@ class BaseProxy(object):
         self._search_up = search_up
         self._multiplier = None
 
+    def __str__(self):
+        if self._search_self and not self._search_up:
+            s = 'Self'
+        elif not self._search_self and self._search_up:
+            s = 'Parent'
+        else:
+            s = 'ConfusedProxy'
+        return s + '.' + self.path()
+
     def __setattr__(self, attr, value):
         if not attr.startswith('_'):
             raise AttributeError, \
@@ -102,6 +111,9 @@ class BaseProxy(object):
         return obj
     getindex = staticmethod(getindex)
 
+    # This method should be called once the proxy is assigned to a
+    # particular parameter or port to set the expected type of the
+    # resolved proxy
     def set_param_desc(self, pdesc):
         self._pdesc = pdesc
 
-- 
cgit v1.2.3