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