MEM: Pass the ports from Python to C++ using the Swig params
[gem5.git] / src / python / m5 / proxy.py
index 36995397be3a434c6339cd23f3b616a120525350..a2926589293f66ab9d6a3ca73390ab1a1d63de86 100644 (file)
 #
 #####################################################################
 
+import copy
+
 class BaseProxy(object):
     def __init__(self, search_self, search_up):
         self._search_self = search_self
         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 +113,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
 
@@ -117,15 +131,22 @@ class AttrProxy(BaseProxy):
             return super(AttrProxy, self).__getattr__(self, attr)
         if hasattr(self, '_pdesc'):
             raise AttributeError, "Attribute reference on bound proxy"
-        self._modifiers.append(attr)
-        return self
+        # Return a copy of self rather than modifying self in place
+        # since self could be an indirect reference via a variable or
+        # parameter
+        new_self = copy.deepcopy(self)
+        new_self._modifiers.append(attr)
+        return new_self
 
     # support indexing on proxies (e.g., Self.cpu[0])
     def __getitem__(self, key):
         if not isinstance(key, int):
             raise TypeError, "Proxy object requires integer index"
-        self._modifiers.append(key)
-        return self
+        if hasattr(self, '_pdesc'):
+            raise AttributeError, "Index operation on bound proxy"
+        new_self = copy.deepcopy(self)
+        new_self._modifiers.append(key)
+        return new_self
 
     def find(self, obj):
         try:
@@ -163,6 +184,13 @@ class AnyProxy(BaseProxy):
     def path(self):
         return 'any'
 
+class AllProxy(BaseProxy):
+    def find(self, obj):
+        return obj.find_all(self._pdesc.ptype)
+
+    def path(self):
+        return 'all'
+
 def isproxy(obj):
     if isinstance(obj, (BaseProxy, params.EthernetAddr)):
         return True
@@ -180,6 +208,10 @@ class ProxyFactory(object):
     def __getattr__(self, attr):
         if attr == 'any':
             return AnyProxy(self.search_self, self.search_up)
+        elif attr == 'all':
+            if self.search_up:
+                assert("Parant.all is not supported")
+            return AllProxy(self.search_self, self.search_up)
         else:
             return AttrProxy(self.search_self, self.search_up, attr)