X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;ds=sidebyside;f=python%2Fm5%2Fconfig.py;h=64ec994906ee3a5b12062017e18695aac078a55c;hb=3d51dc41329823d46eab055a9200ed579a2141f7;hp=74022059f1e94ea6630f26edb6d3a4a63499d866;hpb=d94f5bfb04a9e5e99242f960ca20a6e693e6ad56;p=gem5.git diff --git a/python/m5/config.py b/python/m5/config.py index 74022059f..64ec99490 100644 --- a/python/m5/config.py +++ b/python/m5/config.py @@ -27,7 +27,7 @@ from __future__ import generators import os, re, sys, types, inspect -from smartdict import SmartDict +from m5 import panic from convert import * noDot = False @@ -36,16 +36,6 @@ try: except: noDot = True -env = SmartDict() -env.update(os.environ) - -def panic(string): - print >>sys.stderr, 'panic:', string - sys.exit(1) - -def issequence(value): - return isinstance(value, tuple) or isinstance(value, list) - class Singleton(type): def __call__(cls, *args, **kwargs): if hasattr(cls, '_instance'): @@ -150,25 +140,91 @@ class Singleton(type): ##################################################################### class Proxy(object): - def __init__(self, path = ()): + def __init__(self, path): self._object = None - self._path = path + if path == 'any': + self._path = None + else: + # path is a list of (attr,index) tuples + self._path = [(path,None)] + self._index = None + self._multiplier = None def __getattr__(self, attr): - return Proxy(self._path + (attr, )) + if attr == '__bases__': + return super(Proxy, self).__getattr__(self, attr) + self._path.append((attr,None)) + return self def __setattr__(self, attr, value): if not attr.startswith('_'): raise AttributeError, 'cannot set attribute %s' % attr super(Proxy, self).__setattr__(attr, value) - def _convert(self): - obj = self._object - for attr in self._path: - obj = obj.__getattribute__(attr) + # support indexing on proxies (e.g., parent.cpu[0]) + def __getitem__(self, key): + if not isinstance(key, int): + raise TypeError, "Proxy object requires integer index" + if self._path == None: + raise IndexError, "Index applied to 'any' proxy" + # replace index portion of last path element with new index + self._path[-1] = (self._path[-1][0], key) + return self + + # support multiplying proxies by constants + def __mul__(self, other): + if not isinstance(other, int): + raise TypeError, "Proxy multiplier must be integer" + if self._multiplier == None: + self._multiplier = other + else: + # support chained multipliers + self._multiplier *= other + return self + + def _mulcheck(self, result): + if self._multiplier == None: + return result + if not isinstance(result, int): + raise TypeError, "Proxy with multiplier resolves to " \ + "non-integer value" + return result * self._multiplier + + def unproxy(self, base, ptype): + obj = base + done = False + while not done: + if obj is None: + raise AttributeError, \ + 'Parent of %s type %s not found at path %s' \ + % (base.name, ptype, self._path) + result, done = obj.find(ptype, self._path) + obj = obj.parent + + if isinstance(result, Proxy): + result = result.unproxy(obj, ptype) + + return self._mulcheck(result) + + def getindex(obj, index): + if index == None: + return obj + try: + obj = obj[index] + except TypeError: + if index != 0: + raise + # if index is 0 and item is not subscriptable, just + # use item itself (so cpu[0] works on uniprocessors) return obj + getindex = staticmethod(getindex) -Super = Proxy() +class ProxyFactory(object): + def __getattr__(self, attr): + return Proxy(attr) + +# global object for handling parent.foo proxies +parent = ProxyFactory() def isSubClass(value, cls): try: @@ -189,7 +245,7 @@ def isSimObject(value): return False def isSimObjSequence(value): - if not issequence(value): + if not isinstance(value, (list, tuple)): return False for val in value: @@ -463,7 +519,7 @@ class MetaConfigNode(type): if isNullPointer(child) or instance.top_child_names.has_key(name): return - if issequence(child): + if isinstance(child, (list, tuple)): kid = [] for i,c in enumerate(child): n = '%s%d' % (name, i) @@ -491,10 +547,10 @@ class MetaConfigNode(type): for key,value in cls._getvalues().iteritems(): if isConfigNode(value): cls.add_child(instance, key, value) - if issequence(value): - list = [ v for v in value if isConfigNode(v) ] - if len(list): - cls.add_child(instance, key, list) + if isinstance(value, (list, tuple)): + vals = [ v for v in value if isConfigNode(v) ] + if len(vals): + cls.add_child(instance, key, vals) for pname,param in cls._getparams().iteritems(): try: @@ -505,7 +561,7 @@ class MetaConfigNode(type): try: if isConfigNode(value): value = instance.child_objects[value] - elif issequence(value): + elif isinstance(value, (list, tuple)): v = [] for val in value: if isConfigNode(val): @@ -654,50 +710,40 @@ class Node(object): if issubclass(child.realtype, realtype): if obj is not None: raise AttributeError, \ - 'Super matched more than one: %s %s' % \ + 'parent.any matched more than one: %s %s' % \ (obj.path, child.path) obj = child return obj, obj is not None try: obj = self - for node in path[:-1]: - obj = obj.child_names[node] + for (node,index) in path[:-1]: + if obj.child_names.has_key(node): + obj = obj.child_names[node] + else: + obj = obj.top_child_names[node] + obj = Proxy.getindex(obj, index) - last = path[-1] + (last,index) = path[-1] if obj.child_names.has_key(last): value = obj.child_names[last] - if issubclass(value.realtype, realtype): - return value, True + return Proxy.getindex(value, index), True + elif obj.top_child_names.has_key(last): + value = obj.top_child_names[last] + return Proxy.getindex(value, index), True elif obj.param_names.has_key(last): value = obj.param_names[last] realtype._convert(value.value) - return value.value, True + return Proxy.getindex(value.value, index), True except KeyError: pass return None, False - def unproxy(self, ptype, value): - if not isinstance(value, Proxy): - return value - - if value is None: - raise AttributeError, 'Error while fixing up %s' % self.path - - obj = self - done = False - while not done: - if obj is None: - raise AttributeError, \ - 'Parent of %s type %s not found at path %s' \ - % (self.name, ptype, value._path) - found, done = obj.find(ptype, value._path) - if isinstance(found, Proxy): - done = False - obj = obj.parent - - return found + def unproxy(self, param, ptype): + if not isinstance(param, Proxy): + return param + return param.unproxy(self, ptype) def fixup(self): self.all[self.path] = self @@ -707,10 +753,10 @@ class Node(object): pval = param.value try: - if issequence(pval): - param.value = [ self.unproxy(ptype, pv) for pv in pval ] + if isinstance(pval, (list, tuple)): + param.value = [ self.unproxy(pv, ptype) for pv in pval ] else: - param.value = self.unproxy(ptype, pval) + param.value = self.unproxy(pval, ptype) except: print 'Error while fixing up %s:%s' % (self.path, param.name) raise @@ -851,6 +897,9 @@ class Value(object): def __str__(self): return str(self._getattr()) + def __len__(self): + return len(self._getattr()) + # Regular parameter. class _Param(object): def __init__(self, ptype, *args, **kwargs): @@ -960,7 +1009,7 @@ class _VectorParam(_Param): if value == None: return True - if issequence(value): + if isinstance(value, (list, tuple)): for val in value: if not isinstance(val, Proxy): self.ptype._convert(val) @@ -973,7 +1022,7 @@ class _VectorParam(_Param): if value == None: return [] - if issequence(value): + if isinstance(value, (list, tuple)): # list: coerce each element into new list return [ self.ptype._convert(v) for v in value ] else: @@ -981,7 +1030,7 @@ class _VectorParam(_Param): return self.ptype._convert(value) def string(self, value): - if issequence(value): + if isinstance(value, (list, tuple)): return ' '.join([ self.ptype._string(v) for v in value]) else: return self.ptype._string(value) @@ -1347,9 +1396,8 @@ class SimObject(ConfigNode, ParamType): # __all__ defines the list of symbols that get exported when # 'from config import *' is invoked. Try to keep this reasonably # short to avoid polluting other namespaces. -__all__ = ['env', 'issequence', - 'ConfigNode', 'SimObject', 'ParamContext', 'Param', 'VectorParam', - 'Super', 'Enum', +__all__ = ['ConfigNode', 'SimObject', 'ParamContext', 'Param', 'VectorParam', + 'parent', 'Enum', 'Int', 'Unsigned', 'Int8', 'UInt8', 'Int16', 'UInt16', 'Int32', 'UInt32', 'Int64', 'UInt64', 'Counter', 'Addr', 'Tick', 'Percent',