?? config.py
字號:
if not isinstance(other, (int, float)): raise TypeError, "Proxy multiplier must be integer" if self._multiplier == None: self._multiplier = other else: # support chained multipliers self._multiplier *= other return self __rmul__ = __mul__ def _mulcheck(self, result): if self._multiplier == None: return result return result * self._multiplier def unproxy(self, base): obj = base done = False if self._search_self: result, done = self.find(obj) if self._search_up: while not done: try: obj = obj._parent except: break result, done = self.find(obj) if not done: raise AttributeError, "Can't resolve proxy '%s' from '%s'" % \\ (self.path(), base.path()) if isinstance(result, BaseProxy): if result == self: raise RuntimeError, "Cycle in unproxy" result = result.unproxy(obj) 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) def set_param_desc(self, pdesc): self._pdesc = pdescclass AttrProxy(BaseProxy): def __init__(self, search_self, search_up, attr): super(AttrProxy, self).__init__(search_self, search_up) self._attr = attr self._modifiers = [] def __getattr__(self, attr): # python uses __bases__ internally for inheritance if attr.startswith('_'): return super(AttrProxy, self).__getattr__(self, attr) if hasattr(self, '_pdesc'): raise AttributeError, "Attribute reference on bound proxy" self._modifiers.append(attr) return 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 def find(self, obj): try: val = getattr(obj, self._attr) except: return None, False while isproxy(val): val = val.unproxy(obj) for m in self._modifiers: if isinstance(m, str): val = getattr(val, m) elif isinstance(m, int): val = val[m] else: assert("Item must be string or integer") while isproxy(val): val = val.unproxy(obj) return val, True def path(self): p = self._attr for m in self._modifiers: if isinstance(m, str): p += '.%s' % m elif isinstance(m, int): p += '[%d]' % m else: assert("Item must be string or integer") return pclass AnyProxy(BaseProxy): def find(self, obj): return obj.find_any(self._pdesc.ptype) def path(self): return 'any'def isproxy(obj): if isinstance(obj, (BaseProxy, EthernetAddr)): return True elif isinstance(obj, (list, tuple)): for v in obj: if isproxy(v): return True return Falseclass ProxyFactory(object): def __init__(self, search_self, search_up): self.search_self = search_self self.search_up = search_up def __getattr__(self, attr): if attr == 'any': return AnyProxy(self.search_self, self.search_up) else: return AttrProxy(self.search_self, self.search_up, attr)# global objects for handling proxiesParent = ProxyFactory(search_self = False, search_up = True)Self = ProxyFactory(search_self = True, search_up = False)####################################################################### Parameter description classes## The _params dictionary in each class maps parameter names to# either a Param or a VectorParam object. These objects contain the# parameter description string, the parameter type, and the default# value (loaded from the PARAM section of the .odesc files). The# _convert() method on these objects is used to force whatever value# is assigned to the parameter to the appropriate type.## Note that the default values are loaded into the class's attribute# space when the parameter dictionary is initialized (in# MetaConfigNode._setparams()); after that point they aren't used.####################################################################### Dummy base class to identify types that are legitimate for SimObject# parameters.class ParamValue(object): # default for printing to .ini file is regular string conversion. # will be overridden in some cases def ini_str(self): return str(self) # allows us to blithely call unproxy() on things without checking # if they're really proxies or not def unproxy(self, base): return self# Regular parameter description.class ParamDesc(object): def __init__(self, ptype_str, ptype, *args, **kwargs): self.ptype_str = ptype_str # remember ptype only if it is provided if ptype != None: self.ptype = ptype if args: if len(args) == 1: self.desc = args[0] elif len(args) == 2: self.default = args[0] self.desc = args[1] else: raise TypeError, 'too many arguments' if kwargs.has_key('desc'): assert(not hasattr(self, 'desc')) self.desc = kwargs['desc'] del kwargs['desc'] if kwargs.has_key('default'): assert(not hasattr(self, 'default')) self.default = kwargs['default'] del kwargs['default'] if kwargs: raise TypeError, 'extra unknown kwargs %s' % kwargs if not hasattr(self, 'desc'): raise TypeError, 'desc attribute missing' def __getattr__(self, attr): if attr == 'ptype': try: ptype = eval(self.ptype_str, m5.__dict__) if not isinstance(ptype, type): panic("Param qualifier is not a type: %s" % self.ptype) self.ptype = ptype return ptype except NameError: pass raise AttributeError, "'%s' object has no attribute '%s'" % \\ (type(self).__name__, attr) def convert(self, value): if isinstance(value, BaseProxy): value.set_param_desc(self) return value if not hasattr(self, 'ptype') and isNullPointer(value): # deferred evaluation of SimObject; continue to defer if # we're just assigning a null pointer return value if isinstance(value, self.ptype): return value if isNullPointer(value) and issubclass(self.ptype, SimObject): return value return self.ptype(value)# Vector-valued parameter description. Just like ParamDesc, except# that the value is a vector (list) of the specified type instead of a# single value.class VectorParamValue(list): def ini_str(self): return ' '.join([str(v) for v in self]) def unproxy(self, base): return [v.unproxy(base) for v in self]class SimObjVector(VectorParamValue): def print_ini(self): for v in self: v.print_ini()class VectorParamDesc(ParamDesc): # Convert assigned value to appropriate type. If the RHS is not a # list or tuple, it generates a single-element list. def convert(self, value): if isinstance(value, (list, tuple)): # list: coerce each element into new list tmp_list = [ ParamDesc.convert(self, v) for v in value ] if isSimObjSequence(tmp_list): return SimObjVector(tmp_list) else: return VectorParamValue(tmp_list) else: # singleton: leave it be (could coerce to a single-element # list here, but for some historical reason we don't... return ParamDesc.convert(self, value)class ParamFactory(object): def __init__(self, param_desc_class, ptype_str = None): self.param_desc_class = param_desc_class self.ptype_str = ptype_str def __getattr__(self, attr): if self.ptype_str: attr = self.ptype_str + '.' + attr return ParamFactory(self.param_desc_class, attr) # E.g., Param.Int(5, "number of widgets") def __call__(self, *args, **kwargs): caller_frame = inspect.stack()[1][0] ptype = None try: ptype = eval(self.ptype_str, caller_frame.f_globals, caller_frame.f_locals) if not isinstance(ptype, type): raise TypeError, \\ "Param qualifier is not a type: %s" % ptype except NameError: # if name isn't defined yet, assume it's a SimObject, and # try to resolve it later pass return self.param_desc_class(self.ptype_str, ptype, *args, **kwargs)Param = ParamFactory(ParamDesc)VectorParam = ParamFactory(VectorParamDesc)####################################################################### Parameter Types## Though native Python types could be used to specify parameter types# (the 'ptype' field of the Param and VectorParam classes), it's more# flexible to define our own set of types. This gives us more control# over how Python expressions are converted to values (via the# __init__() constructor) and how these values are printed out (via# the __str__() conversion method). Eventually we'll need these types# to correspond to distinct C++ types as well.######################################################################class Range(ParamValue): type = int # default; can be overridden in subclasses def __init__(self, *args, **kwargs): def handle_kwargs(self, kwargs): if 'end' in kwargs: self.second = self.type(kwargs.pop('end')) elif 'size' in kwargs: self.second = self.first + self.type(kwargs.pop('size')) - 1 else: raise TypeError, "Either end or size must be specified" if len(args) == 0: self.first = self.type(kwargs.pop('start')) handle_kwargs(self, kwargs) elif len(args) == 1: if kwargs: self.first = self.type(args[0]) handle_kwargs(self, kwargs) elif isinstance(args[0], Range): self.first = self.type(args[0].first) self.second = self.type(args[0].second) else: self.first = self.type(0) self.second = self.type(args[0]) - 1 elif len(args) == 2: self.first = self.type(args[0]) self.second = self.type(args[1]) else: raise TypeError, "Too many arguments specified" if kwargs: raise TypeError, "too many keywords: %s" % kwargs.keys() def __str__(self): return '%s:%s' % (self.first, self.second)# Metaclass for bounds-checked integer parameters. See CheckedInt.class CheckedIntType(type): def __init__(cls, name, bases, dict): super(CheckedIntType, cls).__init__(name, bases, dict) # CheckedInt is an abstract base class, so we actually don't # want to do any processing on it... the rest of this code is # just for classes that derive from CheckedInt. if name == 'CheckedInt': return if not (hasattr(cls, 'min') and hasattr(cls, 'max')): if not (hasattr(cls, 'size') and hasattr(cls, 'unsigned')): panic("CheckedInt subclass %s must define either\\n" \\ " 'min' and 'max' or 'size' and 'unsigned'\\n" \\ % name); if cls.unsigned: cls.min = 0 cls.max = 2 ** cls.size - 1 else: cls.min = -(2 ** (cls.size - 1)) cls.max = (2 ** (cls.size - 1)) - 1# Abstract superclass for bounds-checked integer parameters. This# class is subclassed to generate parameter classes with specific# bounds. Initialization of the min and max bounds is done in the# metaclass CheckedIntType.__init__.class CheckedInt(long,ParamValue): __metaclass__ = CheckedIntType def __new__(cls, value): if isinstance(value, str): value = toInteger(value) self = long.__new__(cls, value) if not cls.min <= self <= cls.max: raise TypeError, 'Integer param out of bounds %d < %d < %d' % \\ (cls.min, self, cls.max) return self
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -